Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 88

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 215

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 216

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 217

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 218

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 219

Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 220
PK!qll version.rbnu[# frozen_string_literal: true module RDoc ## # RDoc version you are using VERSION = '6.5.1.1' end PK!pmarkup/heading.rbnu[# frozen_string_literal: true ## # A heading with a level (1-6) and text RDoc::Markup::Heading = Struct.new :level, :text do @to_html = nil @to_label = nil ## # A singleton RDoc::Markup::ToLabel formatter for headings. def self.to_label @to_label ||= RDoc::Markup::ToLabel.new end ## # A singleton plain HTML formatter for headings. Used for creating labels # for the Table of Contents def self.to_html return @to_html if @to_html markup = RDoc::Markup.new markup.add_regexp_handling RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF @to_html = RDoc::Markup::ToHtml.new nil def @to_html.handle_regexp_CROSSREF target target.text.sub(/^\\/, '') end @to_html end ## # Calls #accept_heading on +visitor+ def accept visitor visitor.accept_heading self end ## # An HTML-safe anchor reference for this header. def aref "label-#{self.class.to_label.convert text.dup}" end ## # Creates a fully-qualified label which will include the label from # +context+. This helps keep ids unique in HTML. def label context = nil label = aref label = [context.aref, label].compact.join '-' if context and context.respond_to? :aref label end ## # HTML markup of the text of this label without the surrounding header # element. def plain_html self.class.to_html.to_html(text.dup) end def pretty_print q # :nodoc: q.group 2, "[head: #{level} ", ']' do q.pp text end end end PK!ھmarkup/attributes.rbnu[# frozen_string_literal: true ## # We manage a set of attributes. Each attribute has a symbol name and a bit # value. class RDoc::Markup::Attributes ## # The regexp handling attribute type. See RDoc::Markup#add_regexp_handling attr_reader :regexp_handling ## # Creates a new attributes set. def initialize @regexp_handling = 1 @name_to_bitmap = [ [:_REGEXP_HANDLING_, @regexp_handling], ] @next_bitmap = @regexp_handling << 1 end ## # Returns a unique bit for +name+ def bitmap_for name bitmap = @name_to_bitmap.assoc name unless bitmap then bitmap = @next_bitmap @next_bitmap <<= 1 @name_to_bitmap << [name, bitmap] else bitmap = bitmap.last end bitmap end ## # Returns a string representation of +bitmap+ def as_string bitmap return 'none' if bitmap.zero? res = [] @name_to_bitmap.each do |name, bit| res << name if (bitmap & bit) != 0 end res.join ',' end ## # yields each attribute name in +bitmap+ def each_name_of bitmap return enum_for __method__, bitmap unless block_given? @name_to_bitmap.each do |name, bit| next if bit == @regexp_handling yield name.to_s if (bitmap & bit) != 0 end end end PK!ԄEEmarkup/list.rbnu[# frozen_string_literal: true ## # A List is a homogeneous set of ListItems. # # The supported list types include: # # :BULLET:: # An unordered list # :LABEL:: # An unordered definition list, but using an alternate RDoc::Markup syntax # :LALPHA:: # An ordered list using increasing lowercase English letters # :NOTE:: # An unordered definition list # :NUMBER:: # An ordered list using increasing Arabic numerals # :UALPHA:: # An ordered list using increasing uppercase English letters # # Definition lists behave like HTML definition lists. Each list item can # describe multiple terms. See RDoc::Markup::ListItem for how labels and # definition are stored as list items. class RDoc::Markup::List ## # The list's type attr_accessor :type ## # Items in the list attr_reader :items ## # Creates a new list of +type+ with +items+. Valid list types are: # +:BULLET+, +:LABEL+, +:LALPHA+, +:NOTE+, +:NUMBER+, +:UALPHA+ def initialize type = nil, *items @type = type @items = [] @items.concat items end ## # Appends +item+ to the list def << item @items << item end def == other # :nodoc: self.class == other.class and @type == other.type and @items == other.items end ## # Runs this list and all its #items through +visitor+ def accept visitor visitor.accept_list_start self @items.each do |item| item.accept visitor end visitor.accept_list_end self end ## # Is the list empty? def empty? @items.empty? end ## # Returns the last item in the list def last @items.last end def pretty_print q # :nodoc: q.group 2, "[list: #{@type} ", ']' do q.seplist @items do |item| q.pp item end end end ## # Appends +items+ to the list def push *items @items.concat items end end PK!hP)1markup/to_joined_paragraph.rbnu[# frozen_string_literal: true ## # Joins the parts of an RDoc::Markup::Paragraph into a single String. # # This allows for easier maintenance and testing of Markdown support. # # This formatter only works on Paragraph instances. Attempting to process # other markup syntax items will not work. class RDoc::Markup::ToJoinedParagraph < RDoc::Markup::Formatter def initialize # :nodoc: super nil end def start_accepting # :nodoc: end def end_accepting # :nodoc: end ## # Converts the parts of +paragraph+ to a single entry. def accept_paragraph paragraph parts = paragraph.parts.chunk do |part| String === part end.map do |string, chunk| string ? chunk.join.rstrip : chunk end.flatten paragraph.parts.replace parts end alias accept_block_quote ignore alias accept_heading ignore alias accept_list_end ignore alias accept_list_item_end ignore alias accept_list_item_start ignore alias accept_list_start ignore alias accept_raw ignore alias accept_rule ignore alias accept_verbatim ignore alias accept_table ignore end PK!g\''markup/to_html.rbnu[# frozen_string_literal: true require 'cgi/util' ## # Outputs RDoc markup as HTML. class RDoc::Markup::ToHtml < RDoc::Markup::Formatter include RDoc::Text # :section: Utilities ## # Maps RDoc::Markup::Parser::LIST_TOKENS types to HTML tags LIST_TYPE_TO_HTML = { :BULLET => [''], :LABEL => ['
', '
'], :LALPHA => ['
    ', '
'], :NOTE => ['
', '
'], :NUMBER => ['
    ', '
'], :UALPHA => ['
    ', '
'], } attr_reader :res # :nodoc: attr_reader :in_list_entry # :nodoc: attr_reader :list # :nodoc: ## # The RDoc::CodeObject HTML is being generated for. This is used to # generate namespaced URI fragments attr_accessor :code_object ## # Path to this document for relative links attr_accessor :from_path # :section: ## # Creates a new formatter that will output HTML def initialize options, markup = nil super @code_object = nil @from_path = '' @in_list_entry = nil @list = nil @th = nil @hard_break = "
\n" init_regexp_handlings init_tags end # :section: Regexp Handling # # These methods are used by regexp handling markup added by RDoc::Markup#add_regexp_handling. URL_CHARACTERS_REGEXP_STR = /[A-Za-z0-9\-._~:\/\?#\[\]@!$&'\(\)*+,;%=]/.source ## # Adds regexp handlings. def init_regexp_handlings # external links @markup.add_regexp_handling(/(?:link:|https?:|mailto:|ftp:|irc:|www\.)#{URL_CHARACTERS_REGEXP_STR}+\w/, :HYPERLINK) init_link_notation_regexp_handlings end ## # Adds regexp handlings about link notations. def init_link_notation_regexp_handlings add_regexp_handling_RDOCLINK add_regexp_handling_TIDYLINK end def handle_RDOCLINK url # :nodoc: case url when /^rdoc-ref:/ CGI.escapeHTML($') when /^rdoc-label:/ text = $' text = case text when /\Alabel-/ then $' when /\Afootmark-/ then $' when /\Afoottext-/ then $' else text end gen_url CGI.escapeHTML(url), CGI.escapeHTML(text) when /^rdoc-image:/ %[] when /\Ardoc-[a-z]+:/ CGI.escapeHTML($') end end ## # +target+ is a
def handle_regexp_HARD_BREAK target '
' end ## # +target+ is a potential link. The following schemes are handled: # # mailto::: # Inserted as-is. # http::: # Links are checked to see if they reference an image. If so, that image # gets inserted using an tag. Otherwise a conventional # is used. # link::: # Reference to a local file relative to the output directory. def handle_regexp_HYPERLINK(target) url = CGI.escapeHTML(target.text) gen_url url, url end ## # +target+ is an rdoc-schemed link that will be converted into a hyperlink. # # For the +rdoc-ref+ scheme the named reference will be returned without # creating a link. # # For the +rdoc-label+ scheme the footnote and label prefixes are stripped # when creating a link. All other contents will be linked verbatim. def handle_regexp_RDOCLINK target handle_RDOCLINK target.text end ## # This +target+ is a link where the label is different from the URL # label[url] or {long label}[url] def handle_regexp_TIDYLINK(target) text = target.text return text unless text =~ /^\{(.*)\}\[(.*?)\]$/ or text =~ /^(\S+)\[(.*?)\]$/ label = $1 url = CGI.escapeHTML($2) if /^rdoc-image:/ =~ label label = handle_RDOCLINK(label) else label = CGI.escapeHTML(label) end gen_url url, label end # :section: Visitor # # These methods implement the HTML visitor. ## # Prepares the visitor for HTML generation def start_accepting @res = [] @in_list_entry = [] @list = [] end ## # Returns the generated output def end_accepting @res.join end ## # Adds +block_quote+ to the output def accept_block_quote block_quote @res << "\n
" block_quote.parts.each do |part| part.accept self end @res << "
\n" end ## # Adds +paragraph+ to the output def accept_paragraph paragraph @res << "\n

" text = paragraph.text @hard_break text = text.gsub(/\r?\n/, ' ') @res << to_html(text) @res << "

\n" end ## # Adds +verbatim+ to the output def accept_verbatim verbatim text = verbatim.text.rstrip klass = nil content = if verbatim.ruby? or parseable? text then begin tokens = RDoc::Parser::RipperStateLex.parse text klass = ' class="ruby"' result = RDoc::TokenStream.to_html tokens result = result + "\n" unless "\n" == result[-1] result rescue CGI.escapeHTML text end else CGI.escapeHTML text end if @options.pipe then @res << "\n
#{CGI.escapeHTML text}\n
\n" else @res << "\n#{content}\n" end end ## # Adds +rule+ to the output def accept_rule rule @res << "
\n" end ## # Prepares the visitor for consuming +list+ def accept_list_start(list) @list << list.type @res << html_list_name(list.type, true) @in_list_entry.push false end ## # Finishes consumption of +list+ def accept_list_end(list) @list.pop if tag = @in_list_entry.pop @res << tag end @res << html_list_name(list.type, false) << "\n" end ## # Prepares the visitor for consuming +list_item+ def accept_list_item_start(list_item) if tag = @in_list_entry.last @res << tag end @res << list_item_start(list_item, @list.last) end ## # Finishes consumption of +list_item+ def accept_list_item_end(list_item) @in_list_entry[-1] = list_end_for(@list.last) end ## # Adds +blank_line+ to the output def accept_blank_line(blank_line) # @res << annotate("

") << "\n" end ## # Adds +heading+ to the output. The headings greater than 6 are trimmed to # level 6. def accept_heading heading level = [6, heading.level].min label = heading.label @code_object @res << if @options.output_decoration "\n" else "\n" end @res << to_html(heading.text) unless @options.pipe then @res << "" @res << " " end @res << "\n" end ## # Adds +raw+ to the output def accept_raw raw @res << raw.parts.join("\n") end ## # Adds +table+ to the output def accept_table header, body, aligns @res << "\n\n\n\n" header.zip(aligns) do |text, align| @res << '' << to_html(text) << "\n" end @res << "\n\n\n" body.each do |row| @res << "\n" row.zip(aligns) do |text, align| @res << '' << to_html(text) << "\n" end @res << "\n" end @res << "\n
\n" end # :section: Utilities ## # CGI-escapes +text+ def convert_string(text) CGI.escapeHTML text end ## # Generate a link to +url+ with content +text+. Handles the special cases # for img: and link: described under handle_regexp_HYPERLINK def gen_url url, text scheme, url, id = parse_url url if %w[http https link].include?(scheme) and url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then "" else if scheme != 'link' and %r%\A((?!https?:)(?:[^/#]*/)*+)([^/#]+)\.(rb|rdoc|md)(?=\z|#)%i =~ url url = "#$1#{$2.tr('.', '_')}_#$3.html#$'" end text = text.sub %r%^#{scheme}:/*%i, '' text = text.sub %r%^[*\^](\d+)$%, '\1' link = "#{text}" link = "#{link}" if /"foot/ =~ id link end end ## # Determines the HTML list element for +list_type+ and +open_tag+ def html_list_name(list_type, open_tag) tags = LIST_TYPE_TO_HTML[list_type] raise RDoc::Error, "Invalid list type: #{list_type.inspect}" unless tags tags[open_tag ? 0 : 1] end ## # Maps attributes to HTML tags def init_tags add_tag :BOLD, "", "" add_tag :TT, "", "" add_tag :EM, "", "" end ## # Returns the HTML tag for +list_type+, possible using a label from # +list_item+ def list_item_start(list_item, list_type) case list_type when :BULLET, :LALPHA, :NUMBER, :UALPHA then "

  • " when :LABEL, :NOTE then Array(list_item.label).map do |label| "
    #{to_html label}\n" end.join << "
    " else raise RDoc::Error, "Invalid list type: #{list_type.inspect}" end end ## # Returns the HTML end-tag for +list_type+ def list_end_for(list_type) case list_type when :BULLET, :LALPHA, :NUMBER, :UALPHA then "
  • " when :LABEL, :NOTE then "" else raise RDoc::Error, "Invalid list type: #{list_type.inspect}" end end ## # Returns true if text is valid ruby syntax def parseable? text verbose, $VERBOSE = $VERBOSE, nil eval("BEGIN {return true}\n#{text}") rescue SyntaxError false ensure $VERBOSE = verbose end ## # Converts +item+ to HTML using RDoc::Text#to_html def to_html item super convert_flow @am.flow item end end PK!ua1markup/to_bs.rbnu[# frozen_string_literal: true ## # Outputs RDoc markup with hot backspace action! You will probably need a # pager to use this output format. # # This formatter won't work on 1.8.6 because it lacks String#chars. class RDoc::Markup::ToBs < RDoc::Markup::ToRdoc ## # Returns a new ToBs that is ready for hot backspace action! def initialize markup = nil super @in_b = false @in_em = false end ## # Sets a flag that is picked up by #annotate to do the right thing in # #convert_string def init_tags add_tag :BOLD, '+b', '-b' add_tag :EM, '+_', '-_' add_tag :TT, '' , '' # we need in_tt information maintained end ## # Makes heading text bold. def accept_heading heading use_prefix or @res << ' ' * @indent @res << @headings[heading.level][0] @in_b = true @res << attributes(heading.text) @in_b = false @res << @headings[heading.level][1] @res << "\n" end ## # Turns on or off regexp handling for +convert_string+ def annotate tag case tag when '+b' then @in_b = true when '-b' then @in_b = false when '+_' then @in_em = true when '-_' then @in_em = false end '' end ## # Calls convert_string on the result of convert_regexp_handling def convert_regexp_handling target convert_string super end ## # Adds bold or underline mixed with backspaces def convert_string string return string unless @in_b or @in_em chars = if @in_b then string.chars.map do |char| "#{char}\b#{char}" end elsif @in_em then string.chars.map do |char| "_\b#{char}" end end chars.join end end PK!Vmarkup/to_test.rbnu[# frozen_string_literal: true ## # This Markup outputter is used for testing purposes. class RDoc::Markup::ToTest < RDoc::Markup::Formatter # :stopdoc: ## # :section: Visitor def start_accepting @res = [] @list = [] end def end_accepting @res end def accept_paragraph(paragraph) @res << convert_flow(@am.flow(paragraph.text)) end def accept_raw raw @res << raw.parts.join end def accept_verbatim(verbatim) @res << verbatim.text.gsub(/^(\S)/, ' \1') end def accept_list_start(list) @list << case list.type when :BULLET then '*' when :NUMBER then '1' else list.type end end def accept_list_end(list) @list.pop end def accept_list_item_start(list_item) @res << "#{' ' * (@list.size - 1)}#{@list.last}: " end def accept_list_item_end(list_item) end def accept_blank_line(blank_line) @res << "\n" end def accept_heading(heading) @res << "#{'=' * heading.level} #{heading.text}" end def accept_rule(rule) @res << '-' * rule.weight end # :startdoc: end PK!markup/table.rbnu[# frozen_string_literal: true ## # A section of table class RDoc::Markup::Table attr_accessor :header, :align, :body def initialize header, align, body @header, @align, @body = header, align, body end def == other self.class == other.class and @header == other.header and @align == other.align and @body == other.body end def accept visitor visitor.accept_table @header, @body, @align end def pretty_print q # :nodoc: q.group 2, '[Table: ', ']' do q.group 2, '[Head: ', ']' do q.seplist @header.zip(@align) do |text, align| q.pp text if align q.text ":" q.breakable q.text align.to_s end end end q.breakable q.group 2, '[Body: ', ']' do q.seplist @body do |body| q.group 2, '[', ']' do q.seplist body do |text| q.pp text end end end end end end end PK!eMmarkup/to_html_snippet.rbnu[# frozen_string_literal: true ## # Outputs RDoc markup as paragraphs with inline markup only. class RDoc::Markup::ToHtmlSnippet < RDoc::Markup::ToHtml ## # After this many characters the input will be cut off. attr_reader :character_limit ## # The number of characters seen so far. attr_reader :characters # :nodoc: ## # The attribute bitmask attr_reader :mask ## # After this many paragraphs the input will be cut off. attr_reader :paragraph_limit ## # Count of paragraphs found attr_reader :paragraphs ## # Creates a new ToHtmlSnippet formatter that will cut off the input on the # next word boundary after the given number of +characters+ or +paragraphs+ # of text have been encountered. def initialize options, characters = 100, paragraphs = 3, markup = nil super options, markup @character_limit = characters @paragraph_limit = paragraphs @characters = 0 @mask = 0 @paragraphs = 0 @markup.add_regexp_handling RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF end ## # Adds +heading+ to the output as a paragraph def accept_heading heading @res << "

    #{to_html heading.text}\n" add_paragraph end ## # Raw sections are untrusted and ignored alias accept_raw ignore ## # Rules are ignored alias accept_rule ignore def accept_paragraph paragraph para = @in_list_entry.last || "

    " text = paragraph.text @hard_break @res << "#{para}#{to_html text}\n" add_paragraph end ## # Finishes consumption of +list_item+ def accept_list_item_end list_item end ## # Prepares the visitor for consuming +list_item+ def accept_list_item_start list_item @res << list_item_start(list_item, @list.last) end ## # Prepares the visitor for consuming +list+ def accept_list_start list @list << list.type @res << html_list_name(list.type, true) @in_list_entry.push '' end ## # Adds +verbatim+ to the output def accept_verbatim verbatim throw :done if @characters >= @character_limit input = verbatim.text.rstrip text = truncate input text << ' ...' unless text == input super RDoc::Markup::Verbatim.new text add_paragraph end ## # Prepares the visitor for HTML snippet generation def start_accepting super @characters = 0 end ## # Removes escaping from the cross-references in +target+ def handle_regexp_CROSSREF target target.text.sub(/\A\\/, '') end ## # +target+ is a
    def handle_regexp_HARD_BREAK target @characters -= 4 '
    ' end ## # Lists are paragraphs, but notes and labels have a separator def list_item_start list_item, list_type throw :done if @characters >= @character_limit case list_type when :BULLET, :LALPHA, :NUMBER, :UALPHA then "

    " when :LABEL, :NOTE then labels = Array(list_item.label).map do |label| to_html label end.join ', ' labels << " — " unless labels.empty? start = "

    #{labels}" @characters += 1 # try to include the label start else raise RDoc::Error, "Invalid list type: #{list_type.inspect}" end end ## # Returns just the text of +link+, +url+ is only used to determine the link # type. def gen_url url, text if url =~ /^rdoc-label:([^:]*)(?::(.*))?/ then type = "link" elsif url =~ /([A-Za-z]+):(.*)/ then type = $1 else type = "http" end if (type == "http" or type == "https" or type == "link") and url =~ /\.(gif|png|jpg|jpeg|bmp)$/ then '' else text.sub(%r%^#{type}:/*%, '') end end ## # In snippets, there are no lists def html_list_name list_type, open_tag '' end ## # Throws +:done+ when paragraph_limit paragraphs have been encountered def add_paragraph @paragraphs += 1 throw :done if @paragraphs >= @paragraph_limit end ## # Marks up +content+ def convert content catch :done do return super end end_accepting end ## # Converts flow items +flow+ def convert_flow flow throw :done if @characters >= @character_limit res = [] @mask = 0 flow.each do |item| case item when RDoc::Markup::AttrChanger then off_tags res, item on_tags res, item when String then text = convert_string item res << truncate(text) when RDoc::Markup::RegexpHandling then text = convert_regexp_handling item res << truncate(text) else raise "Unknown flow element: #{item.inspect}" end if @characters >= @character_limit then off_tags res, RDoc::Markup::AttrChanger.new(0, @mask) break end end res << ' ...' if @characters >= @character_limit res.join end ## # Maintains a bitmask to allow HTML elements to be closed properly. See # RDoc::Markup::Formatter. def on_tags res, item @mask ^= item.turn_on super end ## # Maintains a bitmask to allow HTML elements to be closed properly. See # RDoc::Markup::Formatter. def off_tags res, item @mask ^= item.turn_off super end ## # Truncates +text+ at the end of the first word after the character_limit. def truncate text length = text.length characters = @characters @characters += length return text if @characters < @character_limit remaining = @character_limit - characters text =~ /\A(.{#{remaining},}?)(\s|$)/m # TODO word-break instead of \s? $1 end end PK!Тmarkup/indented_paragraph.rbnu[# frozen_string_literal: true ## # An Indented Paragraph of text class RDoc::Markup::IndentedParagraph < RDoc::Markup::Raw ## # The indent in number of spaces attr_reader :indent ## # Creates a new IndentedParagraph containing +parts+ indented with +indent+ # spaces def initialize indent, *parts @indent = indent super(*parts) end def == other # :nodoc: super and indent == other.indent end ## # Calls #accept_indented_paragraph on +visitor+ def accept visitor visitor.accept_indented_paragraph self end ## # Joins the raw paragraph text and converts inline HardBreaks to the # +hard_break+ text followed by the indent. def text hard_break = nil @parts.map do |part| if RDoc::Markup::HardBreak === part then '%1$s%3$*2$s' % [hard_break, @indent, ' '] if hard_break else part end end.join end end PK! t{llmarkup/to_markdown.rbnu[# frozen_string_literal: true # :markup: markdown ## # Outputs parsed markup as Markdown class RDoc::Markup::ToMarkdown < RDoc::Markup::ToRdoc ## # Creates a new formatter that will output Markdown format text def initialize markup = nil super @headings[1] = ['# ', ''] @headings[2] = ['## ', ''] @headings[3] = ['### ', ''] @headings[4] = ['#### ', ''] @headings[5] = ['##### ', ''] @headings[6] = ['###### ', ''] add_regexp_handling_RDOCLINK add_regexp_handling_TIDYLINK @hard_break = " \n" end ## # Maps attributes to HTML sequences def init_tags add_tag :BOLD, '**', '**' add_tag :EM, '*', '*' add_tag :TT, '`', '`' end ## # Adds a newline to the output def handle_regexp_HARD_BREAK target " \n" end ## # Finishes consumption of `list` def accept_list_end list @res << "\n" super end ## # Finishes consumption of `list_item` def accept_list_item_end list_item width = case @list_type.last when :BULLET then 4 when :NOTE, :LABEL then use_prefix 4 else @list_index[-1] = @list_index.last.succ 4 end @indent -= width end ## # Prepares the visitor for consuming `list_item` def accept_list_item_start list_item type = @list_type.last case type when :NOTE, :LABEL then bullets = Array(list_item.label).map do |label| attributes(label).strip end.join "\n" bullets << "\n:" @prefix = ' ' * @indent @indent += 4 @prefix << bullets + (' ' * (@indent - 1)) else bullet = type == :BULLET ? '*' : @list_index.last.to_s + '.' @prefix = (' ' * @indent) + bullet.ljust(4) @indent += 4 end end ## # Prepares the visitor for consuming `list` def accept_list_start list case list.type when :BULLET, :LABEL, :NOTE then @list_index << nil when :LALPHA, :NUMBER, :UALPHA then @list_index << 1 else raise RDoc::Error, "invalid list type #{list.type}" end @list_width << 4 @list_type << list.type end ## # Adds `rule` to the output def accept_rule rule use_prefix or @res << ' ' * @indent @res << '-' * 3 @res << "\n" end ## # Outputs `verbatim` indented 4 columns def accept_verbatim verbatim indent = ' ' * (@indent + 4) verbatim.parts.each do |part| @res << indent unless part == "\n" @res << part end @res << "\n" end ## # Creates a Markdown-style URL from +url+ with +text+. def gen_url url, text scheme, url, = parse_url url "[#{text.sub(%r{^#{scheme}:/*}i, '')}](#{url})" end ## # Handles rdoc- type links for footnotes. def handle_rdoc_link url case url when /^rdoc-ref:/ then $' when /^rdoc-label:footmark-(\d+)/ then "[^#{$1}]:" when /^rdoc-label:foottext-(\d+)/ then "[^#{$1}]" when /^rdoc-label:label-/ then gen_url url, $' when /^rdoc-image:/ then "![](#{$'})" when /^rdoc-[a-z]+:/ then $' end end ## # Converts the RDoc markup tidylink into a Markdown.style link. def handle_regexp_TIDYLINK target text = target.text return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/ label = $1 url = $2 if url =~ /^rdoc-label:foot/ then handle_rdoc_link url else gen_url url, label end end ## # Converts the rdoc-...: links into a Markdown.style links. def handle_regexp_RDOCLINK target handle_rdoc_link target.text end end PK!fQ`66markup/to_ansi.rbnu[# frozen_string_literal: true ## # Outputs RDoc markup with vibrant ANSI color! class RDoc::Markup::ToAnsi < RDoc::Markup::ToRdoc ## # Creates a new ToAnsi visitor that is ready to output vibrant ANSI color! def initialize markup = nil super @headings.clear @headings[1] = ["\e[1;32m", "\e[m"] # bold @headings[2] = ["\e[4;32m", "\e[m"] # underline @headings[3] = ["\e[32m", "\e[m"] # just green end ## # Maps attributes to ANSI sequences def init_tags add_tag :BOLD, "\e[1m", "\e[m" add_tag :TT, "\e[7m", "\e[m" add_tag :EM, "\e[4m", "\e[m" end ## # Overrides indent width to ensure output lines up correctly. def accept_list_item_end list_item width = case @list_type.last when :BULLET then 2 when :NOTE, :LABEL then if @prefix then @res << @prefix.strip @prefix = nil end @res << "\n" unless res.length == 1 2 else bullet = @list_index.last.to_s @list_index[-1] = @list_index.last.succ bullet.length + 2 end @indent -= width end ## # Adds coloring to note and label list items def accept_list_item_start list_item bullet = case @list_type.last when :BULLET then '*' when :NOTE, :LABEL then labels = Array(list_item.label).map do |label| attributes(label).strip end.join "\n" labels << ":\n" unless labels.empty? labels else @list_index.last.to_s + '.' end case @list_type.last when :NOTE, :LABEL then @indent += 2 @prefix = bullet + (' ' * @indent) else @prefix = (' ' * @indent) + bullet.ljust(bullet.length + 1) width = bullet.gsub(/\e\[[\d;]*m/, '').length + 1 @indent += width end end ## # Starts accepting with a reset screen def start_accepting super @res = ["\e[0m"] end end PK!&#[[markup/to_label.rbnu[# frozen_string_literal: true require 'cgi/util' ## # Creates HTML-safe labels suitable for use in id attributes. Tidylinks are # converted to their link part and cross-reference links have the suppression # marks removed (\\SomeClass is converted to SomeClass). class RDoc::Markup::ToLabel < RDoc::Markup::Formatter attr_reader :res # :nodoc: ## # Creates a new formatter that will output HTML-safe labels def initialize markup = nil super nil, markup @markup.add_regexp_handling RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF @markup.add_regexp_handling(/(((\{.*?\})|\b\S+?)\[\S+?\])/, :TIDYLINK) add_tag :BOLD, '', '' add_tag :TT, '', '' add_tag :EM, '', '' @res = [] end ## # Converts +text+ to an HTML-safe label def convert text label = convert_flow @am.flow text CGI.escape(label).gsub('%', '-').sub(/^-/, '') end ## # Converts the CROSSREF +target+ to plain text, removing the suppression # marker, if any def handle_regexp_CROSSREF target text = target.text text.sub(/^\\/, '') end ## # Converts the TIDYLINK +target+ to just the text part def handle_regexp_TIDYLINK target text = target.text return text unless text =~ /\{(.*?)\}\[(.*?)\]/ or text =~ /(\S+)\[(.*?)\]/ $1 end alias accept_blank_line ignore alias accept_block_quote ignore alias accept_heading ignore alias accept_list_end ignore alias accept_list_item_end ignore alias accept_list_item_start ignore alias accept_list_start ignore alias accept_paragraph ignore alias accept_raw ignore alias accept_rule ignore alias accept_verbatim ignore alias end_accepting ignore alias handle_regexp_HARD_BREAK ignore alias start_accepting ignore end PK!C"==markup/include.rbnu[# frozen_string_literal: true ## # A file included at generation time. Objects of this class are created by # RDoc::RD for an extension-less include. # # This implementation in incomplete. class RDoc::Markup::Include ## # The filename to be included, without extension attr_reader :file ## # Directories to search for #file attr_reader :include_path ## # Creates a new include that will import +file+ from +include_path+ def initialize file, include_path @file = file @include_path = include_path end def == other # :nodoc: self.class === other and @file == other.file and @include_path == other.include_path end def pretty_print q # :nodoc: q.group 2, '[incl ', ']' do q.text file q.breakable q.text 'from ' q.pp include_path end end end PK!WY markup/document.rbnu[# frozen_string_literal: true ## # A Document containing lists, headings, paragraphs, etc. class RDoc::Markup::Document include Enumerable ## # The file this document was created from. See also # RDoc::ClassModule#add_comment attr_reader :file ## # If a heading is below the given level it will be omitted from the # table_of_contents attr_accessor :omit_headings_below ## # The parts of the Document attr_reader :parts ## # Creates a new Document with +parts+ def initialize *parts @parts = [] @parts.concat parts @file = nil @omit_headings_from_table_of_contents_below = nil end ## # Appends +part+ to the document def << part case part when RDoc::Markup::Document then unless part.empty? then parts.concat part.parts parts << RDoc::Markup::BlankLine.new end when String then raise ArgumentError, "expected RDoc::Markup::Document and friends, got String" unless part.empty? else parts << part end end def == other # :nodoc: self.class == other.class and @file == other.file and @parts == other.parts end ## # Runs this document and all its #items through +visitor+ def accept visitor visitor.start_accepting visitor.accept_document self visitor.end_accepting end ## # Concatenates the given +parts+ onto the document def concat parts self.parts.concat parts end ## # Enumerator for the parts of this document def each &block @parts.each(&block) end ## # Does this document have no parts? def empty? @parts.empty? or (@parts.length == 1 and merged? and @parts.first.empty?) end ## # The file this Document was created from. def file= location @file = case location when RDoc::TopLevel then location.relative_name else location end end ## # When this is a collection of documents (#file is not set and this document # contains only other documents as its direct children) #merge replaces # documents in this class with documents from +other+ when the file matches # and adds documents from +other+ when the files do not. # # The information in +other+ is preferred over the receiver def merge other if empty? then @parts = other.parts return self end other.parts.each do |other_part| self.parts.delete_if do |self_part| self_part.file and self_part.file == other_part.file end self.parts << other_part end self end ## # Does this Document contain other Documents? def merged? RDoc::Markup::Document === @parts.first end def pretty_print q # :nodoc: start = @file ? "[doc (#{@file}): " : '[doc: ' q.group 2, start, ']' do q.seplist @parts do |part| q.pp part end end end ## # Appends +parts+ to the document def push *parts self.parts.concat parts end ## # Returns an Array of headings in the document. # # Require 'rdoc/markup/formatter' before calling this method. def table_of_contents accept RDoc::Markup::ToTableOfContents.to_toc end end PK!fcrmarkup/list_item.rbnu[# frozen_string_literal: true ## # An item within a List that contains paragraphs, headings, etc. # # For BULLET, NUMBER, LALPHA and UALPHA lists, the label will always be nil. # For NOTE and LABEL lists, the list label may contain: # # * a single String for a single label # * an Array of Strings for a list item with multiple terms # * nil for an extra description attached to a previously labeled list item class RDoc::Markup::ListItem ## # The label for the ListItem attr_accessor :label ## # Parts of the ListItem attr_reader :parts ## # Creates a new ListItem with an optional +label+ containing +parts+ def initialize label = nil, *parts @label = label @parts = [] @parts.concat parts end ## # Appends +part+ to the ListItem def << part @parts << part end def == other # :nodoc: self.class == other.class and @label == other.label and @parts == other.parts end ## # Runs this list item and all its #parts through +visitor+ def accept visitor visitor.accept_list_item_start self @parts.each do |part| part.accept visitor end visitor.accept_list_item_end self end ## # Is the ListItem empty? def empty? @parts.empty? end ## # Length of parts in the ListItem def length @parts.length end def pretty_print q # :nodoc: q.group 2, '[item: ', ']' do case @label when Array then q.pp @label q.text ';' q.breakable when String then q.pp @label q.text ';' q.breakable end q.seplist @parts do |part| q.pp part end end end ## # Adds +parts+ to the ListItem def push *parts @parts.concat parts end end PK!;;markup/rule.rbnu[# frozen_string_literal: true ## # A horizontal rule with a weight class RDoc::Markup::Rule < Struct.new :weight ## # Calls #accept_rule on +visitor+ def accept visitor visitor.accept_rule self end def pretty_print q # :nodoc: q.group 2, '[rule:', ']' do q.pp weight end end end PK!ߦomarkup/attr_changer.rbnu[# frozen_string_literal: true class RDoc::Markup AttrChanger = Struct.new :turn_on, :turn_off # :nodoc: end ## # An AttrChanger records a change in attributes. It contains a bitmap of the # attributes to turn on, and a bitmap of those to turn off. class RDoc::Markup::AttrChanger def to_s # :nodoc: "Attr: +#{turn_on}/-#{turn_off}" end def inspect # :nodoc: '+%d/-%d' % [turn_on, turn_off] end end PK!%Fmarkup/formatter.rbnu[# frozen_string_literal: true ## # Base class for RDoc markup formatters # # Formatters are a visitor that converts an RDoc::Markup tree (from a comment) # into some kind of output. RDoc ships with formatters for converting back to # rdoc, ANSI text, HTML, a Table of Contents and other formats. # # If you'd like to write your own Formatter use # RDoc::Markup::FormatterTestCase. If you're writing a text-output formatter # use RDoc::Markup::TextFormatterTestCase which provides extra test cases. class RDoc::Markup::Formatter ## # Tag for inline markup containing a +bit+ for the bitmask and the +on+ and # +off+ triggers. InlineTag = Struct.new(:bit, :on, :off) ## # Converts a target url to one that is relative to a given path def self.gen_relative_url path, target from = File.dirname path to, to_file = File.split target from = from.split "/" to = to.split "/" from.delete '.' to.delete '.' while from.size > 0 and to.size > 0 and from[0] == to[0] do from.shift to.shift end from.fill ".." from.concat to from << to_file File.join(*from) end ## # Creates a new Formatter def initialize options, markup = nil @options = options @markup = markup || RDoc::Markup.new @am = @markup.attribute_manager @am.add_regexp_handling(/
    /, :HARD_BREAK) @attributes = @am.attributes @attr_tags = [] @in_tt = 0 @tt_bit = @attributes.bitmap_for :TT @hard_break = '' @from_path = '.' end ## # Adds +document+ to the output def accept_document document document.parts.each do |item| case item when RDoc::Markup::Document then # HACK accept_document item else item.accept self end end end ## # Adds a regexp handling for links of the form rdoc-...: def add_regexp_handling_RDOCLINK @markup.add_regexp_handling(/rdoc-[a-z]+:[^\s\]]+/, :RDOCLINK) end ## # Adds a regexp handling for links of the form {}[] and # [] def add_regexp_handling_TIDYLINK @markup.add_regexp_handling(/(?: \{.*?\} | # multi-word label \b[^\s{}]+? # single-word label ) \[\S+?\] # link target /x, :TIDYLINK) end ## # Add a new set of tags for an attribute. We allow separate start and end # tags for flexibility def add_tag(name, start, stop) attr = @attributes.bitmap_for name @attr_tags << InlineTag.new(attr, start, stop) end ## # Allows +tag+ to be decorated with additional information. def annotate(tag) tag end ## # Marks up +content+ def convert content @markup.convert content, self end ## # Converts flow items +flow+ def convert_flow(flow) res = [] flow.each do |item| case item when String then res << convert_string(item) when RDoc::Markup::AttrChanger then off_tags res, item on_tags res, item when RDoc::Markup::RegexpHandling then res << convert_regexp_handling(item) else raise "Unknown flow element: #{item.inspect}" end end res.join end ## # Converts added regexp handlings. See RDoc::Markup#add_regexp_handling def convert_regexp_handling target return target.text if in_tt? handled = false @attributes.each_name_of target.type do |name| method_name = "handle_regexp_#{name}" if respond_to? method_name then target.text = public_send method_name, target handled = true end end unless handled then target_name = @attributes.as_string target.type raise RDoc::Error, "Unhandled regexp handling #{target_name}: #{target}" end target.text end ## # Converts a string to be fancier if desired def convert_string string string end ## # Use ignore in your subclass to ignore the content of a node. # # ## # # We don't support raw nodes in ToNoRaw # # alias accept_raw ignore def ignore *node end ## # Are we currently inside tt tags? def in_tt? @in_tt > 0 end ## # Turns on tags for +item+ on +res+ def on_tags res, item attr_mask = item.turn_on return if attr_mask.zero? @attr_tags.each do |tag| if attr_mask & tag.bit != 0 then res << annotate(tag.on) @in_tt += 1 if tt? tag end end end ## # Turns off tags for +item+ on +res+ def off_tags res, item attr_mask = item.turn_off return if attr_mask.zero? @attr_tags.reverse_each do |tag| if attr_mask & tag.bit != 0 then @in_tt -= 1 if tt? tag res << annotate(tag.off) end end end ## # Extracts and a scheme, url and an anchor id from +url+ and returns them. def parse_url url case url when /^rdoc-label:([^:]*)(?::(.*))?/ then scheme = 'link' path = "##{$1}" id = " id=\"#{$2}\"" if $2 when /([A-Za-z]+):(.*)/ then scheme = $1.downcase path = $2 when /^#/ then else scheme = 'http' path = url url = url end if scheme == 'link' then url = if path[0, 1] == '#' then # is this meaningful? path else self.class.gen_relative_url @from_path, path end end [scheme, url, id] end ## # Is +tag+ a tt tag? def tt? tag tag.bit == @tt_bit end end PK!markup/to_rdoc.rbnu[# frozen_string_literal: true ## # Outputs RDoc markup as RDoc markup! (mostly) class RDoc::Markup::ToRdoc < RDoc::Markup::Formatter ## # Current indent amount for output in characters attr_accessor :indent ## # Output width in characters attr_accessor :width ## # Stack of current list indexes for alphabetic and numeric lists attr_reader :list_index ## # Stack of list types attr_reader :list_type ## # Stack of list widths for indentation attr_reader :list_width ## # Prefix for the next list item. See #use_prefix attr_reader :prefix ## # Output accumulator attr_reader :res ## # Creates a new formatter that will output (mostly) \RDoc markup def initialize markup = nil super nil, markup @markup.add_regexp_handling(/\\\S/, :SUPPRESSED_CROSSREF) @width = 78 init_tags @headings = {} @headings.default = [] @headings[1] = ['= ', ''] @headings[2] = ['== ', ''] @headings[3] = ['=== ', ''] @headings[4] = ['==== ', ''] @headings[5] = ['===== ', ''] @headings[6] = ['====== ', ''] @hard_break = "\n" end ## # Maps attributes to HTML sequences def init_tags add_tag :BOLD, "", "" add_tag :TT, "", "" add_tag :EM, "", "" end ## # Adds +blank_line+ to the output def accept_blank_line blank_line @res << "\n" end ## # Adds +paragraph+ to the output def accept_block_quote block_quote @indent += 2 block_quote.parts.each do |part| @prefix = '> ' part.accept self end @indent -= 2 end ## # Adds +heading+ to the output def accept_heading heading use_prefix or @res << ' ' * @indent @res << @headings[heading.level][0] @res << attributes(heading.text) @res << @headings[heading.level][1] @res << "\n" end ## # Finishes consumption of +list+ def accept_list_end list @list_index.pop @list_type.pop @list_width.pop end ## # Finishes consumption of +list_item+ def accept_list_item_end list_item width = case @list_type.last when :BULLET then 2 when :NOTE, :LABEL then if @prefix then @res << @prefix.strip @prefix = nil end @res << "\n" 2 else bullet = @list_index.last.to_s @list_index[-1] = @list_index.last.succ bullet.length + 2 end @indent -= width end ## # Prepares the visitor for consuming +list_item+ def accept_list_item_start list_item type = @list_type.last case type when :NOTE, :LABEL then bullets = Array(list_item.label).map do |label| attributes(label).strip end.join "\n" bullets << ":\n" unless bullets.empty? @prefix = ' ' * @indent @indent += 2 @prefix << bullets + (' ' * @indent) else bullet = type == :BULLET ? '*' : @list_index.last.to_s + '.' @prefix = (' ' * @indent) + bullet.ljust(bullet.length + 1) width = bullet.length + 1 @indent += width end end ## # Prepares the visitor for consuming +list+ def accept_list_start list case list.type when :BULLET then @list_index << nil @list_width << 1 when :LABEL, :NOTE then @list_index << nil @list_width << 2 when :LALPHA then @list_index << 'a' @list_width << list.items.length.to_s.length when :NUMBER then @list_index << 1 @list_width << list.items.length.to_s.length when :UALPHA then @list_index << 'A' @list_width << list.items.length.to_s.length else raise RDoc::Error, "invalid list type #{list.type}" end @list_type << list.type end ## # Adds +paragraph+ to the output def accept_paragraph paragraph text = paragraph.text @hard_break wrap attributes text end ## # Adds +paragraph+ to the output def accept_indented_paragraph paragraph @indent += paragraph.indent text = paragraph.text @hard_break wrap attributes text @indent -= paragraph.indent end ## # Adds +raw+ to the output def accept_raw raw @res << raw.parts.join("\n") end ## # Adds +rule+ to the output def accept_rule rule use_prefix or @res << ' ' * @indent @res << '-' * (@width - @indent) @res << "\n" end ## # Outputs +verbatim+ indented 2 columns def accept_verbatim verbatim indent = ' ' * (@indent + 2) verbatim.parts.each do |part| @res << indent unless part == "\n" @res << part end @res << "\n" end ## # Adds +table+ to the output def accept_table header, body, aligns widths = header.zip(body) do |h, b| [h.size, b.size].max end aligns = aligns.map do |a| case a when nil :center when :left :ljust when :right :rjust end end @res << header.zip(widths, aligns) do |h, w, a| h.__send__(a, w) end.join("|").rstrip << "\n" @res << widths.map {|w| "-" * w }.join("|") << "\n" body.each do |row| @res << row.zip(widths, aligns) do |t, w, a| t.__send__(a, w) end.join("|").rstrip << "\n" end end ## # Applies attribute-specific markup to +text+ using RDoc::AttributeManager def attributes text flow = @am.flow text.dup convert_flow flow end ## # Returns the generated output def end_accepting @res.join end ## # Removes preceding \\ from the suppressed crossref +target+ def handle_regexp_SUPPRESSED_CROSSREF target text = target.text text = text.sub('\\', '') unless in_tt? text end ## # Adds a newline to the output def handle_regexp_HARD_BREAK target "\n" end ## # Prepares the visitor for text generation def start_accepting @res = [""] @indent = 0 @prefix = nil @list_index = [] @list_type = [] @list_width = [] end ## # Adds the stored #prefix to the output and clears it. Lists generate a # prefix for later consumption. def use_prefix prefix, @prefix = @prefix, nil @res << prefix if prefix prefix end ## # Wraps +text+ to #width def wrap text return unless text && !text.empty? text_len = @width - @indent text_len = 20 if text_len < 20 next_prefix = ' ' * @indent prefix = @prefix || next_prefix @prefix = nil text.scan(/\G(?:([^ \n]{#{text_len}})(?=[^ \n])|(.{1,#{text_len}})(?:[ \n]|\z))/) do @res << prefix << ($1 || $2) << "\n" prefix = next_prefix end end end PK!ʘw  markup/to_tt_only.rbnu[# frozen_string_literal: true ## # Extracts sections of text enclosed in plus, tt or code. Used to discover # undocumented parameters. class RDoc::Markup::ToTtOnly < RDoc::Markup::Formatter ## # Stack of list types attr_reader :list_type ## # Output accumulator attr_reader :res ## # Creates a new tt-only formatter. def initialize markup = nil super nil, markup add_tag :TT, nil, nil end ## # Adds tts from +block_quote+ to the output def accept_block_quote block_quote tt_sections block_quote.text end ## # Pops the list type for +list+ from #list_type def accept_list_end list @list_type.pop end ## # Pushes the list type for +list+ onto #list_type def accept_list_start list @list_type << list.type end ## # Prepares the visitor for consuming +list_item+ def accept_list_item_start list_item case @list_type.last when :NOTE, :LABEL then Array(list_item.label).map do |label| tt_sections label end.flatten end end ## # Adds +paragraph+ to the output def accept_paragraph paragraph tt_sections(paragraph.text) end ## # Does nothing to +markup_item+ because it doesn't have any user-built # content def do_nothing markup_item end alias accept_blank_line do_nothing # :nodoc: alias accept_heading do_nothing # :nodoc: alias accept_list_item_end do_nothing # :nodoc: alias accept_raw do_nothing # :nodoc: alias accept_rule do_nothing # :nodoc: alias accept_verbatim do_nothing # :nodoc: ## # Extracts tt sections from +text+ def tt_sections text flow = @am.flow text.dup flow.each do |item| case item when String then @res << item if in_tt? when RDoc::Markup::AttrChanger then off_tags res, item on_tags res, item when RDoc::Markup::RegexpHandling then @res << convert_regexp_handling(item) if in_tt? # TODO can this happen? else raise "Unknown flow element: #{item.inspect}" end end res end ## # Returns an Array of items that were wrapped in plus, tt or code. def end_accepting @res.compact end ## # Prepares the visitor for gathering tt sections def start_accepting @res = [] @list_type = [] end end PK!M markup/raw.rbnu[# frozen_string_literal: true ## # A section of text that is added to the output document as-is class RDoc::Markup::Raw ## # The component parts of the list attr_reader :parts ## # Creates a new Raw containing +parts+ def initialize *parts @parts = [] @parts.concat parts end ## # Appends +text+ def << text @parts << text end def == other # :nodoc: self.class == other.class and @parts == other.parts end ## # Calls #accept_raw+ on +visitor+ def accept visitor visitor.accept_raw self end ## # Appends +other+'s parts def merge other @parts.concat other.parts end def pretty_print q # :nodoc: self.class.name =~ /.*::(\w{1,4})/i q.group 2, "[#{$1.downcase}: ", ']' do q.seplist @parts do |part| q.pp part end end end ## # Appends +texts+ onto this Paragraph def push *texts self.parts.concat texts end ## # The raw text def text @parts.join ' ' end end PK!''markup/attribute_manager.rbnu[# frozen_string_literal: true ## # Manages changes of attributes in a block of text unless MatchData.method_defined?(:match_length) using Module.new { refine(MatchData) { def match_length(nth) b, e = offset(nth) e - b if b end } } end class RDoc::Markup::AttributeManager ## # The NUL character NULL = "\000".freeze #-- # We work by substituting non-printing characters in to the text. For now # I'm assuming that I can substitute a character in the range 0..8 for a 7 # bit character without damaging the encoded string, but this might be # optimistic #++ A_PROTECT = 004 # :nodoc: ## # Special mask character to prevent inline markup handling PROTECT_ATTR = A_PROTECT.chr # :nodoc: ## # The attributes enabled for this markup object. attr_reader :attributes ## # This maps delimiters that occur around words (such as *bold* or +tt+) # where the start and end delimiters and the same. This lets us optimize # the regexp attr_reader :matching_word_pairs ## # And this is used when the delimiters aren't the same. In this case the # hash maps a pattern to the attribute character attr_reader :word_pair_map ## # This maps HTML tags to the corresponding attribute char attr_reader :html_tags ## # A \ in front of a character that would normally be processed turns off # processing. We do this by turning \< into <#{PROTECT} attr_reader :protectable ## # And this maps _regexp handling_ sequences to a name. A regexp handling # sequence is something like a WikiWord attr_reader :regexp_handlings ## # A bits of exclusive maps attr_reader :exclusive_bitmap ## # Creates a new attribute manager that understands bold, emphasized and # teletype text. def initialize @html_tags = {} @matching_word_pairs = {} @protectable = %w[<] @regexp_handlings = [] @word_pair_map = {} @exclusive_bitmap = 0 @attributes = RDoc::Markup::Attributes.new add_word_pair "*", "*", :BOLD, true add_word_pair "_", "_", :EM, true add_word_pair "+", "+", :TT, true add_html "em", :EM, true add_html "i", :EM, true add_html "b", :BOLD, true add_html "tt", :TT, true add_html "code", :TT, true end ## # Return an attribute object with the given turn_on and turn_off bits set def attribute(turn_on, turn_off) RDoc::Markup::AttrChanger.new turn_on, turn_off end ## # Changes the current attribute from +current+ to +new+ def change_attribute current, new diff = current ^ new attribute(new & diff, current & diff) end ## # Used by the tests to change attributes by name from +current_set+ to # +new_set+ def changed_attribute_by_name current_set, new_set current = new = 0 current_set.each do |name| current |= @attributes.bitmap_for(name) end new_set.each do |name| new |= @attributes.bitmap_for(name) end change_attribute(current, new) end ## # Copies +start_pos+ to +end_pos+ from the current string def copy_string(start_pos, end_pos) res = @str[start_pos...end_pos] res.gsub!(/\000/, '') res end def exclusive?(attr) (attr & @exclusive_bitmap) != 0 end NON_PRINTING_START = "\1" # :nodoc: NON_PRINTING_END = "\2" # :nodoc: ## # Map attributes like textto the sequence # \001\002\001\003, where is a per-attribute specific # character def convert_attrs(str, attrs, exclusive = false) convert_attrs_matching_word_pairs(str, attrs, exclusive) convert_attrs_word_pair_map(str, attrs, exclusive) end def convert_attrs_matching_word_pairs(str, attrs, exclusive) # first do matching ones tags = @matching_word_pairs.select { |start, bitmap| exclusive == exclusive?(bitmap) }.keys return if tags.empty? tags = "[#{tags.join("")}](?!#{PROTECT_ATTR})" all_tags = "[#{@matching_word_pairs.keys.join("")}](?!#{PROTECT_ATTR})" re = /(?:^|\W|#{all_tags})\K(#{tags})(\1*[#\\]?[\w:#{PROTECT_ATTR}.\/\[\]-]+?\S?)\1(?!\1)(?=#{all_tags}|\W|$)/ 1 while str.gsub!(re) { |orig| a, w = (m = $~).values_at(1, 2) attr = @matching_word_pairs[a] if attrs.set_attrs(m.begin(2), w.length, attr) a = NULL * a.length else a = NON_PRINTING_START + a + NON_PRINTING_END end a + w + a } str.delete!(NON_PRINTING_START + NON_PRINTING_END) end def convert_attrs_word_pair_map(str, attrs, exclusive) # then non-matching unless @word_pair_map.empty? then @word_pair_map.each do |regexp, attr| next unless exclusive == exclusive?(attr) 1 while str.gsub!(regexp) { |orig| w = (m = ($~))[2] updated = attrs.set_attrs(m.begin(2), w.length, attr) if updated NULL * m.match_length(1) + w + NULL * m.match_length(3) else orig end } end end end ## # Converts HTML tags to RDoc attributes def convert_html(str, attrs, exclusive = false) tags = @html_tags.select { |start, bitmap| exclusive == exclusive?(bitmap) }.keys.join '|' 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) { |orig| attr = @html_tags[$1.downcase] html_length = $~.match_length(1) + 2 # "<>".length seq = NULL * html_length attrs.set_attrs($~.begin(2), $~.match_length(2), attr) seq + $2 + seq + NULL } end ## # Converts regexp handling sequences to RDoc attributes def convert_regexp_handlings str, attrs, exclusive = false @regexp_handlings.each do |regexp, attribute| next unless exclusive == exclusive?(attribute) str.scan(regexp) do capture = $~.size == 1 ? 0 : 1 s, e = $~.offset capture attrs.set_attrs s, e - s, attribute | @attributes.regexp_handling end end end ## # Escapes regexp handling sequences of text to prevent conversion to RDoc def mask_protected_sequences # protect __send__, __FILE__, etc. @str.gsub!(/__([a-z]+)__/i, "_#{PROTECT_ATTR}_#{PROTECT_ATTR}\\1_#{PROTECT_ATTR}_#{PROTECT_ATTR}") @str.gsub!(/(\A|[^\\])\\([#{Regexp.escape @protectable.join}])/m, "\\1\\2#{PROTECT_ATTR}") @str.gsub!(/\\(\\[#{Regexp.escape @protectable.join}])/m, "\\1") end ## # Unescapes regexp handling sequences of text def unmask_protected_sequences @str.gsub!(/(.)#{PROTECT_ATTR}/, "\\1\000") end ## # Adds a markup class with +name+ for words wrapped in the +start+ and # +stop+ character. To make words wrapped with "*" bold: # # am.add_word_pair '*', '*', :BOLD def add_word_pair(start, stop, name, exclusive = false) raise ArgumentError, "Word flags may not start with '<'" if start[0,1] == '<' bitmap = @attributes.bitmap_for name if start == stop then @matching_word_pairs[start] = bitmap else pattern = /(#{Regexp.escape start})(\S+)(#{Regexp.escape stop})/ @word_pair_map[pattern] = bitmap end @protectable << start[0,1] @protectable.uniq! @exclusive_bitmap |= bitmap if exclusive end ## # Adds a markup class with +name+ for words surrounded by HTML tag +tag+. # To process emphasis tags: # # am.add_html 'em', :EM def add_html(tag, name, exclusive = false) bitmap = @attributes.bitmap_for name @html_tags[tag.downcase] = bitmap @exclusive_bitmap |= bitmap if exclusive end ## # Adds a regexp handling for +pattern+ with +name+. A simple URL handler # would be: # # @am.add_regexp_handling(/((https?:)\S+\w)/, :HYPERLINK) def add_regexp_handling pattern, name, exclusive = false bitmap = @attributes.bitmap_for(name) @regexp_handlings << [pattern, bitmap] @exclusive_bitmap |= bitmap if exclusive end ## # Processes +str+ converting attributes, HTML and regexp handlings def flow str @str = str.dup mask_protected_sequences @attrs = RDoc::Markup::AttrSpan.new @str.length, @exclusive_bitmap convert_attrs @str, @attrs, true convert_html @str, @attrs, true convert_regexp_handlings @str, @attrs, true convert_attrs @str, @attrs convert_html @str, @attrs convert_regexp_handlings @str, @attrs unmask_protected_sequences split_into_flow end ## # Debug method that prints a string along with its attributes def display_attributes puts puts @str.tr(NULL, "!") bit = 1 16.times do |bno| line = "" @str.length.times do |i| if (@attrs[i] & bit) == 0 line << " " else if bno.zero? line << "S" else line << ("%d" % (bno+1)) end end end puts(line) unless line =~ /^ *$/ bit <<= 1 end end ## # Splits the string into chunks by attribute change def split_into_flow res = [] current_attr = 0 str_len = @str.length # skip leading invisible text i = 0 i += 1 while i < str_len and @str[i].chr == "\0" start_pos = i # then scan the string, chunking it on attribute changes while i < str_len new_attr = @attrs[i] if new_attr != current_attr if i > start_pos res << copy_string(start_pos, i) start_pos = i end res << change_attribute(current_attr, new_attr) current_attr = new_attr if (current_attr & @attributes.regexp_handling) != 0 then i += 1 while i < str_len and (@attrs[i] & @attributes.regexp_handling) != 0 res << RDoc::Markup::RegexpHandling.new(current_attr, copy_string(start_pos, i)) start_pos = i next end end # move on, skipping any invisible characters begin i += 1 end while i < str_len and @str[i].chr == "\0" end # tidy up trailing text if start_pos < str_len res << copy_string(start_pos, str_len) end # and reset to all attributes off res << change_attribute(current_attr, 0) if current_attr != 0 res end end PK!y markup/hard_break.rbnu[# frozen_string_literal: true ## # A hard-break in the middle of a paragraph. class RDoc::Markup::HardBreak @instance = new ## # RDoc::Markup::HardBreak is a singleton def self.new @instance end ## # Calls #accept_hard_break on +visitor+ def accept visitor visitor.accept_hard_break self end def == other # :nodoc: self.class === other end def pretty_print q # :nodoc: q.text "[break]" end end PK!tԇmarkup/blank_line.rbnu[# frozen_string_literal: true ## # An empty line. This class is a singleton. class RDoc::Markup::BlankLine @instance = new ## # RDoc::Markup::BlankLine is a singleton def self.new @instance end ## # Calls #accept_blank_line on +visitor+ def accept visitor visitor.accept_blank_line self end def pretty_print q # :nodoc: q.text 'blankline' end end PK!N_markup/block_quote.rbnu[# frozen_string_literal: true ## # A quoted section which contains markup items. class RDoc::Markup::BlockQuote < RDoc::Markup::Raw ## # Calls #accept_block_quote on +visitor+ def accept visitor visitor.accept_block_quote self end end PK!TZLmarkup/to_table_of_contents.rbnu[# frozen_string_literal: true ## # Extracts just the RDoc::Markup::Heading elements from a # RDoc::Markup::Document to help build a table of contents class RDoc::Markup::ToTableOfContents < RDoc::Markup::Formatter @to_toc = nil ## # Singleton for table-of-contents generation def self.to_toc @to_toc ||= new end ## # Output accumulator attr_reader :res ## # Omits headings with a level less than the given level. attr_accessor :omit_headings_below def initialize # :nodoc: super nil @omit_headings_below = nil end ## # Adds +document+ to the output, using its heading cutoff if present def accept_document document @omit_headings_below = document.omit_headings_below super end ## # Adds +heading+ to the table of contents def accept_heading heading @res << heading unless suppressed? heading end ## # Returns the table of contents def end_accepting @res end ## # Prepares the visitor for text generation def start_accepting @omit_headings_below = nil @res = [] end ## # Returns true if +heading+ is below the display threshold def suppressed? heading return false unless @omit_headings_below heading.level > @omit_headings_below end # :stopdoc: alias accept_block_quote ignore alias accept_raw ignore alias accept_rule ignore alias accept_blank_line ignore alias accept_paragraph ignore alias accept_verbatim ignore alias accept_list_end ignore alias accept_list_item_start ignore alias accept_list_item_end ignore alias accept_list_end_bullet ignore alias accept_list_start ignore alias accept_table ignore # :startdoc: end PK!a{{markup/to_html_crossref.rbnu[# frozen_string_literal: true ## # Subclass of the RDoc::Markup::ToHtml class that supports looking up method # names, classes, etc to create links. RDoc::CrossReference is used to # generate those links based on the current context. class RDoc::Markup::ToHtmlCrossref < RDoc::Markup::ToHtml # :stopdoc: ALL_CROSSREF_REGEXP = RDoc::CrossReference::ALL_CROSSREF_REGEXP CLASS_REGEXP_STR = RDoc::CrossReference::CLASS_REGEXP_STR CROSSREF_REGEXP = RDoc::CrossReference::CROSSREF_REGEXP METHOD_REGEXP_STR = RDoc::CrossReference::METHOD_REGEXP_STR # :startdoc: ## # RDoc::CodeObject for generating references attr_accessor :context ## # Should we show '#' characters on method references? attr_accessor :show_hash ## # Creates a new crossref resolver that generates links relative to +context+ # which lives at +from_path+ in the generated files. '#' characters on # references are removed unless +show_hash+ is true. Only method names # preceded by '#' or '::' are linked, unless +hyperlink_all+ is true. def initialize(options, from_path, context, markup = nil) raise ArgumentError, 'from_path cannot be nil' if from_path.nil? super options, markup @context = context @from_path = from_path @hyperlink_all = @options.hyperlink_all @show_hash = @options.show_hash @cross_reference = RDoc::CrossReference.new @context end def init_link_notation_regexp_handlings add_regexp_handling_RDOCLINK # The crossref must be linked before tidylink because Klass.method[:sym] # will be processed as a tidylink first and will be broken. crossref_re = @options.hyperlink_all ? ALL_CROSSREF_REGEXP : CROSSREF_REGEXP @markup.add_regexp_handling crossref_re, :CROSSREF add_regexp_handling_TIDYLINK end ## # Creates a link to the reference +name+ if the name exists. If +text+ is # given it is used as the link text, otherwise +name+ is used. def cross_reference name, text = nil, code = true lookup = name name = name[1..-1] unless @show_hash if name[0, 1] == '#' if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])@/ text ||= "#{CGI.unescape $'} at #{$1}" code = false else text ||= name end link lookup, text, code end ## # We're invoked when any text matches the CROSSREF pattern. If we find the # corresponding reference, generate a link. If the name we're looking for # contains no punctuation, we look for it up the module/class chain. For # example, ToHtml is found, even without the RDoc::Markup:: prefix, # because we look for it in module Markup first. def handle_regexp_CROSSREF(target) name = target.text return name if name =~ /@[\w-]+\.[\w-]/ # labels that look like emails unless @hyperlink_all then # This ensures that words entirely consisting of lowercase letters will # not have cross-references generated (to suppress lots of erroneous # cross-references to "new" in text, for instance) return name if name =~ /\A[a-z]*\z/ end cross_reference name end ## # Handles rdoc-ref: scheme links and allows RDoc::Markup::ToHtml to # handle other schemes. def handle_regexp_HYPERLINK target return cross_reference $' if target.text =~ /\Ardoc-ref:/ super end ## # +target+ is an rdoc-schemed link that will be converted into a hyperlink. # For the rdoc-ref scheme the cross-reference will be looked up and the # given name will be used. # # All other contents are handled by # {the superclass}[rdoc-ref:RDoc::Markup::ToHtml#handle_regexp_RDOCLINK] def handle_regexp_RDOCLINK target url = target.text case url when /\Ardoc-ref:/ then cross_reference $' else super end end ## # Generates links for rdoc-ref: scheme URLs and allows # RDoc::Markup::ToHtml to handle other schemes. def gen_url url, text return super unless url =~ /\Ardoc-ref:/ name = $' cross_reference name, text, name == text end ## # Creates an HTML link to +name+ with the given +text+. def link name, text, code = true if !(name.end_with?('+@', '-@')) and name =~ /(.*[^#:])@/ name = $1 label = $' end ref = @cross_reference.resolve name, text case ref when String then ref else path = ref.as_href @from_path if code and RDoc::CodeObject === ref and !(RDoc::TopLevel === ref) text = "#{CGI.escapeHTML text}" end if path =~ /#/ then path << "-label-#{label}" elsif ref.sections and ref.sections.any? { |section| label == section.title } then path << "##{label}" else if ref.respond_to?(:aref) path << "##{ref.aref}-label-#{label}" else path << "#label-#{label}" end end if label "#{text}" end end end PK![nA##markup/verbatim.rbnu[# frozen_string_literal: true ## # A section of verbatim text class RDoc::Markup::Verbatim < RDoc::Markup::Raw ## # Format of this verbatim section attr_accessor :format def initialize *parts # :nodoc: super @format = nil end def == other # :nodoc: super and @format == other.format end ## # Calls #accept_verbatim on +visitor+ def accept visitor visitor.accept_verbatim self end ## # Collapses 3+ newlines into two newlines def normalize parts = [] newlines = 0 @parts.each do |part| case part when /^\s*\n/ then newlines += 1 parts << part if newlines == 1 else newlines = 0 parts << part end end parts.pop if parts.last =~ /\A\r?\n\z/ @parts = parts end def pretty_print q # :nodoc: self.class.name =~ /.*::(\w{1,4})/i q.group 2, "[#{$1.downcase}: ", ']' do if @format then q.text "format: #{@format}" q.breakable end q.seplist @parts do |part| q.pp part end end end ## # Is this verbatim section Ruby code? def ruby? @format ||= nil # TODO for older ri data, switch the tree to marshal_dump @format == :ruby end ## # The text of the section def text @parts.join end end PK!|markup/regexp_handling.rbnu[# frozen_string_literal: true ## # Hold details of a regexp handling sequence class RDoc::Markup::RegexpHandling ## # Regexp handling type attr_reader :type ## # Regexp handling text attr_accessor :text ## # Creates a new regexp handling sequence of +type+ with +text+ def initialize(type, text) @type, @text = type, text end ## # Regexp handlings are equal when the have the same text and type def ==(o) self.text == o.text && self.type == o.type end def inspect # :nodoc: "#" % [ object_id, @type, text.dump] end def to_s # :nodoc: "RegexpHandling: type=#{type} text=#{text.dump}" end end PK!dmarkup/paragraph.rbnu[# frozen_string_literal: true ## # A Paragraph of text class RDoc::Markup::Paragraph < RDoc::Markup::Raw ## # Calls #accept_paragraph on +visitor+ def accept visitor visitor.accept_paragraph self end ## # Joins the raw paragraph text and converts inline HardBreaks to the # +hard_break+ text. def text hard_break = '' @parts.map do |part| if RDoc::Markup::HardBreak === part then hard_break else part end end.join end end PK!v!!markup/pre_process.rbnu[# frozen_string_literal: true ## # Handle common directives that can occur in a block of text: # # \:include: filename # # Directives can be escaped by preceding them with a backslash. # # RDoc plugin authors can register additional directives to be handled by # using RDoc::Markup::PreProcess::register. # # Any directive that is not built-in to RDoc (including those registered via # plugins) will be stored in the metadata hash on the CodeObject the comment # is attached to. See RDoc::Markup@Directives for the list of built-in # directives. class RDoc::Markup::PreProcess ## # An RDoc::Options instance that will be filled in with overrides from # directives attr_accessor :options ## # Adds a post-process handler for directives. The handler will be called # with the result RDoc::Comment (or text String) and the code object for the # comment (if any). def self.post_process &block @post_processors << block end ## # Registered post-processors def self.post_processors @post_processors end ## # Registers +directive+ as one handled by RDoc. If a block is given the # directive will be replaced by the result of the block, otherwise the # directive will be removed from the processed text. # # The block will be called with the directive name and the directive # parameter: # # RDoc::Markup::PreProcess.register 'my-directive' do |directive, param| # # replace text, etc. # end def self.register directive, &block @registered[directive] = block end ## # Registered directives def self.registered @registered end ## # Clears all registered directives and post-processors def self.reset @post_processors = [] @registered = {} end reset ## # Creates a new pre-processor for +input_file_name+ that will look for # included files in +include_path+ def initialize(input_file_name, include_path) @input_file_name = input_file_name @include_path = include_path @options = nil end ## # Look for directives in the given +text+. # # Options that we don't handle are yielded. If the block returns false the # directive is restored to the text. If the block returns nil or no block # was given the directive is handled according to the registered directives. # If a String was returned the directive is replaced with the string. # # If no matching directive was registered the directive is restored to the # text. # # If +code_object+ is given and the directive is unknown then the # directive's parameter is set as metadata on the +code_object+. See # RDoc::CodeObject#metadata for details. def handle text, code_object = nil, &block if RDoc::Comment === text then comment = text text = text.text end # regexp helper (square brackets for optional) # $1 $2 $3 $4 $5 # [prefix][\]:directive:[spaces][param]newline text = text.gsub(/^([ \t]*(?:#|\/?\*)?[ \t]*)(\\?):(\w+):([ \t]*)(.+)?(\r?\n|$)/) do # skip something like ':toto::' next $& if $4.empty? and $5 and $5[0, 1] == ':' # skip if escaped next "#$1:#$3:#$4#$5\n" unless $2.empty? # This is not in handle_directive because I didn't want to pass another # argument into it if comment and $3 == 'markup' then next "#{$1.strip}\n" unless $5 comment.format = $5.downcase next "#{$1.strip}\n" end handle_directive $1, $3, $5, code_object, text.encoding, &block end if comment then comment.text = text else comment = text end self.class.post_processors.each do |handler| handler.call comment, code_object end text end ## # Performs the actions described by +directive+ and its parameter +param+. # # +code_object+ is used for directives that operate on a class or module. # +prefix+ is used to ensure the replacement for handled directives is # correct. +encoding+ is used for the include directive. # # For a list of directives in RDoc see RDoc::Markup. #-- # When 1.8.7 support is ditched prefix can be defaulted to '' def handle_directive prefix, directive, param, code_object = nil, encoding = nil blankline = "#{prefix.strip}\n" directive = directive.downcase case directive when 'arg', 'args' then return "#{prefix}:#{directive}: #{param}\n" unless code_object && code_object.kind_of?(RDoc::AnyMethod) code_object.params = param blankline when 'category' then if RDoc::Context === code_object then section = code_object.add_section param code_object.temporary_section = section elsif RDoc::AnyMethod === code_object then code_object.section_title = param end blankline # ignore category if we're not on an RDoc::Context when 'doc' then return blankline unless code_object code_object.document_self = true code_object.force_documentation = true blankline when 'enddoc' then return blankline unless code_object code_object.done_documenting = true blankline when 'include' then filename = param.split(' ', 2).first include_file filename, prefix, encoding when 'main' then @options.main_page = param if @options.respond_to? :main_page blankline when 'nodoc' then return blankline unless code_object code_object.document_self = nil # notify nodoc code_object.document_children = param !~ /all/i blankline when 'notnew', 'not_new', 'not-new' then return blankline unless RDoc::AnyMethod === code_object code_object.dont_rename_initialize = true blankline when 'startdoc' then return blankline unless code_object code_object.start_doc code_object.force_documentation = true blankline when 'stopdoc' then return blankline unless code_object code_object.stop_doc blankline when 'title' then @options.default_title = param if @options.respond_to? :default_title= blankline when 'yield', 'yields' then return blankline unless code_object # remove parameter &block code_object.params = code_object.params.sub(/,?\s*&\w+/, '') if code_object.params code_object.block_params = param blankline else result = yield directive, param if block_given? case result when nil then code_object.metadata[directive] = param if code_object if RDoc::Markup::PreProcess.registered.include? directive then handler = RDoc::Markup::PreProcess.registered[directive] result = handler.call directive, param if handler else result = "#{prefix}:#{directive}: #{param}\n" end when false then result = "#{prefix}:#{directive}: #{param}\n" end result end end ## # Handles the :include: _filename_ directive. # # If the first line of the included file starts with '#', and contains # an encoding information in the form 'coding:' or 'coding=', it is # removed. # # If all lines in the included file start with a '#', this leading '#' # is removed before inclusion. The included content is indented like # the :include: directive. #-- # so all content will be verbatim because of the likely space after '#'? # TODO shift left the whole file content in that case # TODO comment stop/start #-- and #++ in included file must be processed here def include_file name, indent, encoding full_name = find_include_file name unless full_name then warn "Couldn't find file to include '#{name}' from #{@input_file_name}" return '' end content = RDoc::Encoding.read_file full_name, encoding, true content = RDoc::Encoding.remove_magic_comment content # strip magic comment content = content.sub(/\A# .*coding[=:].*$/, '').lstrip # strip leading '#'s, but only if all lines start with them if content =~ /^[^#]/ then content.gsub(/^/, indent) else content.gsub(/^#?/, indent) end end ## # Look for the given file in the directory containing the current file, # and then in each of the directories specified in the RDOC_INCLUDE path def find_include_file(name) to_search = [File.dirname(@input_file_name)].concat @include_path to_search.each do |dir| full_name = File.join(dir, name) stat = File.stat(full_name) rescue next return full_name if stat.readable? end nil end end PK!Wmarkup/attr_span.rbnu[# frozen_string_literal: true ## # An array of attributes which parallels the characters in a string. class RDoc::Markup::AttrSpan ## # Creates a new AttrSpan for +length+ characters def initialize(length, exclusive) @attrs = Array.new(length, 0) @exclusive = exclusive end ## # Toggles +bits+ from +start+ to +length+ def set_attrs(start, length, bits) updated = false for i in start ... (start+length) if (@exclusive & @attrs[i]) == 0 || (@exclusive & bits) != 0 @attrs[i] |= bits updated = true end end updated end ## # Accesses flags for character +n+ def [](n) @attrs[n] end end PK!p9C99markup/parser.rbnu[# frozen_string_literal: true require 'strscan' ## # A recursive-descent parser for RDoc markup. # # The parser tokenizes an input string then parses the tokens into a Document. # Documents can be converted into output formats by writing a visitor like # RDoc::Markup::ToHTML. # # The parser only handles the block-level constructs Paragraph, List, # ListItem, Heading, Verbatim, BlankLine, Rule and BlockQuote. # Inline markup such as \+blah\+ is handled separately by # RDoc::Markup::AttributeManager. # # To see what markup the Parser implements read RDoc. To see how to use # RDoc markup to format text in your program read RDoc::Markup. class RDoc::Markup::Parser include RDoc::Text ## # List token types LIST_TOKENS = [ :BULLET, :LABEL, :LALPHA, :NOTE, :NUMBER, :UALPHA, ] ## # Parser error subclass class Error < RuntimeError; end ## # Raised when the parser is unable to handle the given markup class ParseError < Error; end ## # Enables display of debugging information attr_accessor :debug ## # Token accessor attr_reader :tokens ## # Parses +str+ into a Document. # # Use RDoc::Markup#parse instead of this method. def self.parse str parser = new parser.tokenize str doc = RDoc::Markup::Document.new parser.parse doc end ## # Returns a token stream for +str+, for testing def self.tokenize str parser = new parser.tokenize str parser.tokens end ## # Creates a new Parser. See also ::parse def initialize @binary_input = nil @current_token = nil @debug = false @s = nil @tokens = [] end ## # Builds a Heading of +level+ def build_heading level type, text, = get text = case type when :TEXT then skip :NEWLINE text else unget '' end RDoc::Markup::Heading.new level, text end ## # Builds a List flush to +margin+ def build_list margin p :list_start => margin if @debug list = RDoc::Markup::List.new label = nil until @tokens.empty? do type, data, column, = get case type when *LIST_TOKENS then if column < margin || (list.type && list.type != type) then unget break end list.type = type peek_type, _, column, = peek_token case type when :NOTE, :LABEL then label = [] unless label if peek_type == :NEWLINE then # description not on the same line as LABEL/NOTE # skip the trailing newline & any blank lines below while peek_type == :NEWLINE get peek_type, _, column, = peek_token end # we may be: # - at end of stream # - at a column < margin: # [text] # blah blah blah # - at the same column, but with a different type of list item # [text] # * blah blah # - at the same column, with the same type of list item # [one] # [two] # In all cases, we have an empty description. # In the last case only, we continue. if peek_type.nil? || column < margin then empty = true elsif column == margin then case peek_type when type empty = :continue when *LIST_TOKENS empty = true else empty = false end else empty = false end if empty then label << data next if empty == :continue break end end else data = nil end if label then data = label << data label = nil end list_item = RDoc::Markup::ListItem.new data parse list_item, column list << list_item else unget break end end p :list_end => margin if @debug if list.empty? then return nil unless label return nil unless [:LABEL, :NOTE].include? list.type list_item = RDoc::Markup::ListItem.new label, RDoc::Markup::BlankLine.new list << list_item end list end ## # Builds a Paragraph that is flush to +margin+ def build_paragraph margin p :paragraph_start => margin if @debug paragraph = RDoc::Markup::Paragraph.new until @tokens.empty? do type, data, column, = get if type == :TEXT and column == margin then paragraph << data break if peek_token.first == :BREAK data << ' ' if skip :NEWLINE else unget break end end paragraph.parts.last.sub!(/ \z/, '') # cleanup p :paragraph_end => margin if @debug paragraph end ## # Builds a Verbatim that is indented from +margin+. # # The verbatim block is shifted left (the least indented lines start in # column 0). Each part of the verbatim is one line of text, always # terminated by a newline. Blank lines always consist of a single newline # character, and there is never a single newline at the end of the verbatim. def build_verbatim margin p :verbatim_begin => margin if @debug verbatim = RDoc::Markup::Verbatim.new min_indent = nil generate_leading_spaces = true line = ''.dup until @tokens.empty? do type, data, column, = get if type == :NEWLINE then line << data verbatim << line line = ''.dup generate_leading_spaces = true next end if column <= margin unget break end if generate_leading_spaces then indent = column - margin line << ' ' * indent min_indent = indent if min_indent.nil? || indent < min_indent generate_leading_spaces = false end case type when :HEADER then line << '=' * data _, _, peek_column, = peek_token peek_column ||= column + data indent = peek_column - column - data line << ' ' * indent when :RULE then width = 2 + data line << '-' * width _, _, peek_column, = peek_token peek_column ||= column + width indent = peek_column - column - width line << ' ' * indent when :BREAK, :TEXT then line << data when :BLOCKQUOTE then line << '>>>' peek_type, _, peek_column = peek_token if peek_type != :NEWLINE and peek_column line << ' ' * (peek_column - column - 3) end else # *LIST_TOKENS list_marker = case type when :BULLET then data when :LABEL then "[#{data}]" when :NOTE then "#{data}::" else # :LALPHA, :NUMBER, :UALPHA "#{data}." end line << list_marker peek_type, _, peek_column = peek_token unless peek_type == :NEWLINE then peek_column ||= column + list_marker.length indent = peek_column - column - list_marker.length line << ' ' * indent end end end verbatim << line << "\n" unless line.empty? verbatim.parts.each { |p| p.slice!(0, min_indent) unless p == "\n" } if min_indent > 0 verbatim.normalize p :verbatim_end => margin if @debug verbatim end ## # Pulls the next token from the stream. def get @current_token = @tokens.shift p :get => @current_token if @debug @current_token end ## # Parses the tokens into an array of RDoc::Markup::XXX objects, # and appends them to the passed +parent+ RDoc::Markup::YYY object. # # Exits at the end of the token stream, or when it encounters a token # in a column less than +indent+ (unless it is a NEWLINE). # # Returns +parent+. def parse parent, indent = 0 p :parse_start => indent if @debug until @tokens.empty? do type, data, column, = get case type when :BREAK then parent << RDoc::Markup::BlankLine.new skip :NEWLINE, false next when :NEWLINE then # trailing newlines are skipped below, so this is a blank line parent << RDoc::Markup::BlankLine.new skip :NEWLINE, false next end # indentation change: break or verbatim if column < indent then unget break elsif column > indent then unget parent << build_verbatim(indent) next end # indentation is the same case type when :HEADER then parent << build_heading(data) when :RULE then parent << RDoc::Markup::Rule.new(data) skip :NEWLINE when :TEXT then unget parse_text parent, indent when :BLOCKQUOTE then nil while (type, = get; type) and type != :NEWLINE _, _, column, = peek_token bq = RDoc::Markup::BlockQuote.new p :blockquote_start => [data, column] if @debug parse bq, column p :blockquote_end => indent if @debug parent << bq when *LIST_TOKENS then unget parent << build_list(indent) else type, data, column, line = @current_token raise ParseError, "Unhandled token #{type} (#{data.inspect}) at #{line}:#{column}" end end p :parse_end => indent if @debug parent end ## # Small hook that is overridden by RDoc::TomDoc def parse_text parent, indent # :nodoc: parent << build_paragraph(indent) end ## # Returns the next token on the stream without modifying the stream def peek_token token = @tokens.first || [] p :peek => token if @debug token end ## # A simple wrapper of StringScanner that is aware of the current column and lineno class MyStringScanner def initialize(input) @line = @column = 0 @s = StringScanner.new input end def scan(re) ret = @s.scan(re) @column += ret.length if ret ret end def unscan(s) @s.pos -= s.bytesize @column -= s.length end def pos [@column, @line] end def newline! @column = 0 @line += 1 end def eos? @s.eos? end def matched @s.matched end def [](i) @s[i] end end ## # Creates the StringScanner def setup_scanner input @s = MyStringScanner.new input end ## # Skips the next token if its type is +token_type+. # # Optionally raises an error if the next token is not of the expected type. def skip token_type, error = true type, = get return unless type # end of stream return @current_token if token_type == type unget raise ParseError, "expected #{token_type} got #{@current_token.inspect}" if error end ## # Turns text +input+ into a stream of tokens def tokenize input setup_scanner input until @s.eos? do pos = @s.pos # leading spaces will be reflected by the column of the next token # the only thing we loose are trailing spaces at the end of the file next if @s.scan(/ +/) # note: after BULLET, LABEL, etc., # indent will be the column of the next non-newline token @tokens << case # [CR]LF => :NEWLINE when @s.scan(/\r?\n/) then token = [:NEWLINE, @s.matched, *pos] @s.newline! token # === text => :HEADER then :TEXT when @s.scan(/(=+)(\s*)/) then level = @s[1].length header = [:HEADER, level, *pos] if @s[2] =~ /^\r?\n/ then @s.unscan(@s[2]) header else pos = @s.pos @s.scan(/.*/) @tokens << header [:TEXT, @s.matched.sub(/\r$/, ''), *pos] end # --- (at least 3) and nothing else on the line => :RULE when @s.scan(/(-{3,}) *\r?$/) then [:RULE, @s[1].length - 2, *pos] # * or - followed by white space and text => :BULLET when @s.scan(/([*-]) +(\S)/) then @s.unscan(@s[2]) [:BULLET, @s[1], *pos] # A. text, a. text, 12. text => :UALPHA, :LALPHA, :NUMBER when @s.scan(/([a-z]|\d+)\. +(\S)/i) then # FIXME if tab(s), the column will be wrong # either support tabs everywhere by first expanding them to # spaces, or assume that they will have been replaced # before (and provide a check for that at least in debug # mode) list_label = @s[1] @s.unscan(@s[2]) list_type = case list_label when /[a-z]/ then :LALPHA when /[A-Z]/ then :UALPHA when /\d/ then :NUMBER else raise ParseError, "BUG token #{list_label}" end [list_type, list_label, *pos] # [text] followed by spaces or end of line => :LABEL when @s.scan(/\[(.*?)\]( +|\r?$)/) then [:LABEL, @s[1], *pos] # text:: followed by spaces or end of line => :NOTE when @s.scan(/(.*?)::( +|\r?$)/) then [:NOTE, @s[1], *pos] # >>> followed by end of line => :BLOCKQUOTE when @s.scan(/>>> *(\w+)?$/) then if word = @s[1] @s.unscan(word) end [:BLOCKQUOTE, word, *pos] # anything else: :TEXT else @s.scan(/(.*?)( )?\r?$/) token = [:TEXT, @s[1], *pos] if @s[2] then @tokens << token [:BREAK, @s[2], pos[0] + @s[1].length, pos[1]] else token end end end self end ## # Returns the current token to the token stream def unget token = @current_token p :unget => token if @debug raise Error, 'too many #ungets' if token == @tokens.first @tokens.unshift token if token end end PK! !Verbio.rbnu[# 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, safe_level = nil, legacy_trim_mode = nil, legacy_eoutvar = 'io', trim_mode: nil, eoutvar: 'io' if RUBY_VERSION >= '2.6' super(str, trim_mode: trim_mode, eoutvar: eoutvar) else super(str, safe_level, legacy_trim_mode, legacy_eoutvar) end 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 PK!#"VVrd.rbnu[# frozen_string_literal: true ## # RDoc::RD implements the RD format from the rdtool gem. # # To choose RD as your only default format see # RDoc::Options@Saved+Options for instructions on setting up a # .doc_options file to store your project default. # # == LICENSE # # The grammar that produces RDoc::RD::BlockParser and RDoc::RD::InlineParser # is included in RDoc under the Ruby License. # # You can find the original source for rdtool at # https://github.com/uwabami/rdtool/ # # You can use, re-distribute or change these files under Ruby's License or GPL. # # 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. class RDoc::RD ## # Parses +rd+ source and returns an RDoc::Markup::Document. If the # =begin or =end lines are missing they will be added. def self.parse rd rd = rd.lines.to_a if rd.find { |i| /\S/ === i } and !rd.find{|i| /^=begin\b/ === i } then rd.unshift("=begin\n").push("=end\n") end parser = RDoc::RD::BlockParser.new document = parser.parse rd # isn't this always true? document.parts.shift if RDoc::Markup::BlankLine === document.parts.first document.parts.pop if RDoc::Markup::BlankLine === document.parts.last document end autoload :BlockParser, "#{__dir__}/rd/block_parser" autoload :InlineParser, "#{__dir__}/rd/inline_parser" autoload :Inline, "#{__dir__}/rd/inline" end PK!T߆text.rbnu[# frozen_string_literal: true ## # For RDoc::Text#to_html require 'strscan' ## # Methods for manipulating comment text module RDoc::Text attr_accessor :language ## # Maps markup formats to classes that can parse them. If the format is # unknown, "rdoc" format is used. MARKUP_FORMAT = { 'markdown' => RDoc::Markdown, 'rdoc' => RDoc::Markup, 'rd' => RDoc::RD, 'tomdoc' => RDoc::TomDoc, } MARKUP_FORMAT.default = RDoc::Markup ## # Maps an encoding to a Hash of characters properly transcoded for that # encoding. # # See also encode_fallback. TO_HTML_CHARACTERS = Hash.new do |h, encoding| h[encoding] = { :close_dquote => encode_fallback('”', encoding, '"'), :close_squote => encode_fallback('’', encoding, '\''), :copyright => encode_fallback('©', encoding, '(c)'), :ellipsis => encode_fallback('…', encoding, '...'), :em_dash => encode_fallback('—', encoding, '---'), :en_dash => encode_fallback('–', encoding, '--'), :open_dquote => encode_fallback('“', encoding, '"'), :open_squote => encode_fallback('‘', encoding, '\''), :trademark => encode_fallback('®', encoding, '(r)'), } end ## # Transcodes +character+ to +encoding+ with a +fallback+ character. def self.encode_fallback character, encoding, fallback character.encode(encoding, :fallback => { character => fallback }, :undef => :replace, :replace => fallback) end ## # Expands tab characters in +text+ to eight spaces def expand_tabs text expanded = [] text.each_line do |line| nil while line.gsub!(/(?:\G|\r)((?:.{8})*?)([^\t\r\n]{0,7})\t/) do r = "#{$1}#{$2}#{' ' * (8 - $2.size)}" r = RDoc::Encoding.change_encoding r, text.encoding r end expanded << line end expanded.join end ## # Flush +text+ left based on the shortest line def flush_left text indent = 9999 text.each_line do |line| line_indent = line =~ /\S/ || 9999 indent = line_indent if indent > line_indent end empty = '' empty = RDoc::Encoding.change_encoding empty, text.encoding text.gsub(/^ {0,#{indent}}/, empty) end ## # Convert a string in markup format into HTML. # # Requires the including class to implement #formatter def markup text if @store.rdoc.options locale = @store.rdoc.options.locale else locale = nil end if locale i18n_text = RDoc::I18n::Text.new(text) text = i18n_text.translate(locale) end parse(text).accept formatter end ## # Strips hashes, expands tabs then flushes +text+ to the left def normalize_comment text return text if text.empty? case language when :ruby text = strip_hashes text when :c text = strip_stars text end text = expand_tabs text text = flush_left text text = strip_newlines text text end ## # Normalizes +text+ then builds a RDoc::Markup::Document from it def parse text, format = 'rdoc' return text if RDoc::Markup::Document === text return text.parse if RDoc::Comment === text text = normalize_comment text # TODO remove, should not be necessary return RDoc::Markup::Document.new if text =~ /\A\n*\z/ MARKUP_FORMAT[format].parse text end ## # The first +limit+ characters of +text+ as HTML def snippet text, limit = 100 document = parse text RDoc::Markup::ToHtmlSnippet.new(options, limit).convert document end ## # Strips leading # characters from +text+ def strip_hashes text return text if text =~ /^(?>\s*)[^\#]/ empty = '' empty = RDoc::Encoding.change_encoding empty, text.encoding text.gsub(/^\s*(#+)/) { $1.tr '#', ' ' }.gsub(/^\s+$/, empty) end ## # Strips leading and trailing \n characters from +text+ def strip_newlines text text.gsub(/\A\n*(.*?)\n*\z/m) do $1 end # block preserves String encoding end ## # Strips /* */ style comments def strip_stars text return text unless text =~ %r%/\*.*\*/%m encoding = text.encoding text = text.gsub %r%Document-method:\s+[\w:.#=!?|^&<>~+\-/*\%@`\[\]]+%, '' space = ' ' space = RDoc::Encoding.change_encoding space, encoding if encoding text.sub! %r%/\*+% do space * $&.length end text.sub! %r%\*+/% do space * $&.length end text.gsub! %r%^[ \t]*\*%m do space * $&.length end empty = '' empty = RDoc::Encoding.change_encoding empty, encoding if encoding text.gsub(/^\s+$/, empty) end ## # Converts ampersand, dashes, ellipsis, quotes, copyright and registered # trademark symbols in +text+ to properly encoded characters. def to_html text html = (''.encode text.encoding).dup encoded = RDoc::Text::TO_HTML_CHARACTERS[text.encoding] s = StringScanner.new text insquotes = false indquotes = false after_word = nil until s.eos? do case when s.scan(/<(tt|code)>.*?<\/\1>/) then # skip contents of tt html << s.matched.gsub('\\\\', '\\') when s.scan(/<(tt|code)>.*?/) then warn "mismatched <#{s[1]}> tag" # TODO signal file/line html << s.matched when s.scan(/<[^>]+\/?s*>/) then # skip HTML tags html << s.matched when s.scan(/\\(\S)/) then # unhandled suppressed crossref html << s[1] after_word = nil when s.scan(/\.\.\.(\.?)/) then html << s[1] << encoded[:ellipsis] after_word = nil when s.scan(/\(c\)/i) then html << encoded[:copyright] after_word = nil when s.scan(/\(r\)/i) then html << encoded[:trademark] after_word = nil when s.scan(/---/) then html << encoded[:em_dash] after_word = nil when s.scan(/--/) then html << encoded[:en_dash] after_word = nil when s.scan(/"|"/) then html << encoded[indquotes ? :close_dquote : :open_dquote] indquotes = !indquotes after_word = nil when s.scan(/``/) then # backtick double quote html << encoded[:open_dquote] after_word = nil when s.scan(/(?:'|'){2}/) then # tick double quote html << encoded[:close_dquote] after_word = nil when s.scan(/`/) then # backtick if insquotes or after_word html << '`' after_word = false else html << encoded[:open_squote] insquotes = true end when s.scan(/'|'/) then # single quote if insquotes html << encoded[:close_squote] insquotes = false elsif after_word # Mary's dog, my parents' house: do not start paired quotes html << encoded[:close_squote] else html << encoded[:open_squote] insquotes = true end after_word = nil else # advance to the next potentially significant character match = s.scan(/.+?(?=[<\\.("'`&-])/) #" if match then html << match after_word = match =~ /\w$/ else html << s.rest break end end end html end ## # Wraps +txt+ to +line_len+ def wrap(txt, line_len = 76) res = [] sp = 0 ep = txt.length while sp < ep # scan back for a space p = sp + line_len - 1 if p >= ep p = ep else while p > sp and txt[p] != ?\s p -= 1 end if p <= sp p = sp + line_len while p < ep and txt[p] != ?\s p += 1 end end end res << txt[sp...p] << "\n" sp = p sp += 1 while sp < ep and txt[sp] == ?\s end res.join.strip end end PK!Ȅ anon_class.rbnu[# frozen_string_literal: true ## # An anonymous class like: # # c = Class.new do end # # AnonClass is currently not used. class RDoc::AnonClass < RDoc::ClassModule end PK!; options.rbnu[# frozen_string_literal: true require 'optparse' require 'pathname' ## # RDoc::Options handles the parsing and storage of options # # == Saved Options # # You can save some options like the markup format in the # .rdoc_options file in your gem. The easiest way to do this is: # # rdoc --markup tomdoc --write-options # # Which will automatically create the file and fill it with the options you # specified. # # The following options will not be saved since they interfere with the user's # preferences or with the normal operation of RDoc: # # * +--coverage-report+ # * +--dry-run+ # * +--encoding+ # * +--force-update+ # * +--format+ # * +--pipe+ # * +--quiet+ # * +--template+ # * +--verbose+ # # == Custom Options # # Generators can hook into RDoc::Options to add generator-specific command # line options. # # When --format is encountered in ARGV, RDoc calls ::setup_options on # the generator class to add extra options to the option parser. Options for # custom generators must occur after --format. rdoc --help # will list options for all installed generators. # # Example: # # class RDoc::Generator::Spellcheck # RDoc::RDoc.add_generator self # # def self.setup_options rdoc_options # op = rdoc_options.option_parser # # op.on('--spell-dictionary DICTIONARY', # RDoc::Options::Path) do |dictionary| # rdoc_options.spell_dictionary = dictionary # end # end # end # # Of course, RDoc::Options does not respond to +spell_dictionary+ by default # so you will need to add it: # # class RDoc::Options # # ## # # The spell dictionary used by the spell-checking plugin. # # attr_accessor :spell_dictionary # # end # # == Option Validators # # OptionParser validators will validate and cast user input values. In # addition to the validators that ship with OptionParser (String, Integer, # Float, TrueClass, FalseClass, Array, Regexp, Date, Time, URI, etc.), # RDoc::Options adds Path, PathArray and Template. class RDoc::Options ## # The deprecated options. DEPRECATED = { '--accessor' => 'support discontinued', '--diagram' => 'support discontinued', '--help-output' => 'support discontinued', '--image-format' => 'was an option for --diagram', '--inline-source' => 'source code is now always inlined', '--merge' => 'ri now always merges class information', '--one-file' => 'support discontinued', '--op-name' => 'support discontinued', '--opname' => 'support discontinued', '--promiscuous' => 'files always only document their content', '--ri-system' => 'Ruby installers use other techniques', } ## # RDoc options ignored (or handled specially) by --write-options SPECIAL = %w[ coverage_report dry_run encoding files force_output force_update generator generator_name generator_options generators op_dir page_dir option_parser pipe rdoc_include root static_path stylesheet_url template template_dir update_output_dir verbosity write_options ] ## # Option validator for OptionParser that matches a directory that exists on # the filesystem. Directory = Object.new ## # Option validator for OptionParser that matches a file or directory that # exists on the filesystem. Path = Object.new ## # Option validator for OptionParser that matches a comma-separated list of # files or directories that exist on the filesystem. PathArray = Object.new ## # Option validator for OptionParser that matches a template directory for an # installed generator that lives in # "rdoc/generator/template/#{template_name}" Template = Object.new ## # Character-set for HTML output. #encoding is preferred over #charset attr_accessor :charset ## # If true, RDoc will not write any files. attr_accessor :dry_run ## # The output encoding. All input files will be transcoded to this encoding. # # The default encoding is UTF-8. This is set via --encoding. attr_accessor :encoding ## # Files matching this pattern will be excluded attr_writer :exclude ## # The list of files to be processed attr_accessor :files ## # Create the output even if the output directory does not look # like an rdoc output directory attr_accessor :force_output ## # Scan newer sources than the flag file if true. attr_accessor :force_update ## # Formatter to mark up text with attr_accessor :formatter ## # Description of the output generator (set with the --format option) attr_accessor :generator ## # For #== attr_reader :generator_name # :nodoc: ## # Loaded generator options. Used to prevent --help from loading the same # options multiple times. attr_accessor :generator_options ## # Old rdoc behavior: hyperlink all words that match a method name, # even if not preceded by '#' or '::' attr_accessor :hyperlink_all ## # Include line numbers in the source code attr_accessor :line_numbers ## # The output locale. attr_accessor :locale ## # The directory where locale data live. attr_accessor :locale_dir ## # Name of the file, class or module to display in the initial index page (if # not specified the first file we encounter is used) attr_accessor :main_page ## # The default markup format. The default is 'rdoc'. 'markdown', 'tomdoc' # and 'rd' are also built-in. attr_accessor :markup ## # If true, only report on undocumented files attr_accessor :coverage_report ## # The name of the output directory attr_accessor :op_dir ## # The OptionParser for this instance attr_accessor :option_parser ## # Output heading decorations? attr_accessor :output_decoration ## # Directory where guides, FAQ, and other pages not associated with a class # live. You may leave this unset if these are at the root of your project. attr_accessor :page_dir ## # Is RDoc in pipe mode? attr_accessor :pipe ## # Array of directories to search for files to satisfy an :include: attr_accessor :rdoc_include ## # Root of the source documentation will be generated for. Set this when # building documentation outside the source directory. Defaults to the # current directory. attr_accessor :root ## # Include the '#' at the front of hyperlinked instance method names attr_accessor :show_hash ## # Directory to copy static files from attr_accessor :static_path ## # The number of columns in a tab attr_accessor :tab_width ## # Template to be used when generating output attr_accessor :template ## # Directory the template lives in attr_accessor :template_dir ## # Additional template stylesheets attr_accessor :template_stylesheets ## # Documentation title attr_accessor :title ## # Should RDoc update the timestamps in the output dir? attr_accessor :update_output_dir ## # Verbosity, zero means quiet attr_accessor :verbosity ## # URL of web cvs frontend attr_accessor :webcvs ## # Minimum visibility of a documented method. One of +:public+, +:protected+, # +:private+ or +:nodoc+. # # The +:nodoc+ visibility ignores all directives related to visibility. The # other visibilities may be overridden on a per-method basis with the :doc: # directive. attr_reader :visibility ## # Indicates if files of test suites should be skipped attr_accessor :skip_tests def initialize loaded_options = nil # :nodoc: init_ivars override loaded_options if loaded_options end def init_ivars # :nodoc: @dry_run = false @exclude = %w[ ~\z \.orig\z \.rej\z \.bak\z \.gemspec\z ] @files = nil @force_output = false @force_update = true @generator = nil @generator_name = nil @generator_options = [] @generators = RDoc::RDoc::GENERATORS @hyperlink_all = false @line_numbers = false @locale = nil @locale_name = nil @locale_dir = 'locale' @main_page = nil @markup = 'rdoc' @coverage_report = false @op_dir = nil @page_dir = nil @pipe = false @output_decoration = true @rdoc_include = [] @root = Pathname(Dir.pwd) @show_hash = false @static_path = [] @stylesheet_url = nil # TODO remove in RDoc 4 @tab_width = 8 @template = nil @template_dir = nil @template_stylesheets = [] @title = nil @update_output_dir = true @verbosity = 1 @visibility = :protected @webcvs = nil @write_options = false @encoding = Encoding::UTF_8 @charset = @encoding.name @skip_tests = true end def init_with map # :nodoc: init_ivars encoding = map['encoding'] @encoding = encoding ? Encoding.find(encoding) : encoding @charset = map['charset'] @exclude = map['exclude'] @generator_name = map['generator_name'] @hyperlink_all = map['hyperlink_all'] @line_numbers = map['line_numbers'] @locale_name = map['locale_name'] @locale_dir = map['locale_dir'] @main_page = map['main_page'] @markup = map['markup'] @op_dir = map['op_dir'] @show_hash = map['show_hash'] @tab_width = map['tab_width'] @template_dir = map['template_dir'] @title = map['title'] @visibility = map['visibility'] @webcvs = map['webcvs'] @rdoc_include = sanitize_path map['rdoc_include'] @static_path = sanitize_path map['static_path'] end def yaml_initialize tag, map # :nodoc: init_with map end def override map # :nodoc: if map.has_key?('encoding') encoding = map['encoding'] @encoding = encoding ? Encoding.find(encoding) : encoding end @charset = map['charset'] if map.has_key?('charset') @exclude = map['exclude'] if map.has_key?('exclude') @generator_name = map['generator_name'] if map.has_key?('generator_name') @hyperlink_all = map['hyperlink_all'] if map.has_key?('hyperlink_all') @line_numbers = map['line_numbers'] if map.has_key?('line_numbers') @locale_name = map['locale_name'] if map.has_key?('locale_name') @locale_dir = map['locale_dir'] if map.has_key?('locale_dir') @main_page = map['main_page'] if map.has_key?('main_page') @markup = map['markup'] if map.has_key?('markup') @op_dir = map['op_dir'] if map.has_key?('op_dir') @page_dir = map['page_dir'] if map.has_key?('page_dir') @show_hash = map['show_hash'] if map.has_key?('show_hash') @tab_width = map['tab_width'] if map.has_key?('tab_width') @template_dir = map['template_dir'] if map.has_key?('template_dir') @title = map['title'] if map.has_key?('title') @visibility = map['visibility'] if map.has_key?('visibility') @webcvs = map['webcvs'] if map.has_key?('webcvs') if map.has_key?('rdoc_include') @rdoc_include = sanitize_path map['rdoc_include'] end if map.has_key?('static_path') @static_path = sanitize_path map['static_path'] end end def == other # :nodoc: self.class === other and @encoding == other.encoding and @generator_name == other.generator_name and @hyperlink_all == other.hyperlink_all and @line_numbers == other.line_numbers and @locale == other.locale and @locale_dir == other.locale_dir and @main_page == other.main_page and @markup == other.markup and @op_dir == other.op_dir and @rdoc_include == other.rdoc_include and @show_hash == other.show_hash and @static_path == other.static_path and @tab_width == other.tab_width and @template == other.template and @title == other.title and @visibility == other.visibility and @webcvs == other.webcvs end ## # Check that the files on the command line exist def check_files @files.delete_if do |file| if File.exist? file then if File.readable? file then false else warn "file '#{file}' not readable" true end else warn "file '#{file}' not found" true end end end ## # Ensure only one generator is loaded def check_generator if @generator then raise OptionParser::InvalidOption, "generator already set to #{@generator_name}" end end ## # Set the title, but only if not already set. Used to set the title # from a source file, so that a title set from the command line # will have the priority. def default_title=(string) @title ||= string end ## # For dumping YAML def to_yaml(*options) # :nodoc: encoding = @encoding ? @encoding.name : nil yaml = {} yaml['encoding'] = encoding yaml['static_path'] = sanitize_path(@static_path) yaml['rdoc_include'] = sanitize_path(@rdoc_include) yaml['page_dir'] = (sanitize_path([@page_dir]).first if @page_dir) ivars = instance_variables.map { |ivar| ivar.to_s[1..-1] } ivars -= SPECIAL ivars.sort.each do |ivar| yaml[ivar] = instance_variable_get("@#{ivar}") end yaml.to_yaml end ## # Create a regexp for #exclude def exclude if @exclude.nil? or Regexp === @exclude then # done, #finish is being re-run @exclude elsif @exclude.empty? then nil else Regexp.new(@exclude.join("|")) end end ## # Completes any unfinished option setup business such as filtering for # existent files, creating a regexp for #exclude and setting a default # #template. def finish if @write_options then write_options exit end @op_dir ||= 'doc' @rdoc_include << "." if @rdoc_include.empty? root = @root.to_s @rdoc_include << root unless @rdoc_include.include?(root) @exclude = self.exclude finish_page_dir check_files # If no template was specified, use the default template for the output # formatter unless @template then @template = @generator_name @template_dir = template_dir_for @template end if @locale_name @locale = RDoc::I18n::Locale[@locale_name] @locale.load(@locale_dir) else @locale = nil end self end ## # Fixes the page_dir to be relative to the root_dir and adds the page_dir to # the files list. def finish_page_dir return unless @page_dir @files << @page_dir page_dir = Pathname(@page_dir) begin page_dir = page_dir.expand_path.relative_path_from @root rescue ArgumentError # On Windows, sometimes crosses different drive letters. page_dir = page_dir.expand_path end @page_dir = page_dir end ## # Returns a properly-space list of generators and their descriptions. def generator_descriptions lengths = [] generators = RDoc::RDoc::GENERATORS.map do |name, generator| lengths << name.length description = generator::DESCRIPTION if generator.const_defined? :DESCRIPTION [name, description] end longest = lengths.max generators.sort.map do |name, description| if description then " %-*s - %s" % [longest, name, description] else " #{name}" end end.join "\n" end ## # Parses command line options. def parse argv ignore_invalid = true argv.insert(0, *ENV['RDOCOPT'].split) if ENV['RDOCOPT'] opts = OptionParser.new do |opt| @option_parser = opt opt.program_name = File.basename $0 opt.version = RDoc::VERSION opt.release = nil opt.summary_indent = ' ' * 4 opt.banner = <<-EOF Usage: #{opt.program_name} [options] [names...] Files are parsed, and the information they contain collected, before any output is produced. This allows cross references between all files to be resolved. If a name is a directory, it is traversed. If no names are specified, all Ruby files in the current directory (and subdirectories) are processed. How RDoc generates output depends on the output formatter being used, and on the options you give. Options can be specified via the RDOCOPT environment variable, which functions similar to the RUBYOPT environment variable for ruby. $ export RDOCOPT="--show-hash" will make rdoc show hashes in method links by default. Command-line options always will override those in RDOCOPT. Available formatters: #{generator_descriptions} RDoc understands the following file formats: EOF parsers = Hash.new { |h,parser| h[parser] = [] } RDoc::Parser.parsers.each do |regexp, parser| parsers[parser.name.sub('RDoc::Parser::', '')] << regexp.source end parsers.sort.each do |parser, regexp| opt.banner += " - #{parser}: #{regexp.join ', '}\n" end opt.banner += " - TomDoc: Only in ruby files\n" opt.banner += "\n The following options are deprecated:\n\n" name_length = DEPRECATED.keys.sort_by { |k| k.length }.last.length DEPRECATED.sort_by { |k,| k }.each do |name, reason| opt.banner += " %*1$2$s %3$s\n" % [-name_length, name, reason] end opt.accept Template do |template| template_dir = template_dir_for template unless template_dir then $stderr.puts "could not find template #{template}" nil else [template, template_dir] end end opt.accept Directory do |directory| directory = File.expand_path directory raise OptionParser::InvalidArgument unless File.directory? directory directory end opt.accept Path do |path| path = File.expand_path path raise OptionParser::InvalidArgument unless File.exist? path path end opt.accept PathArray do |paths,| paths = if paths then paths.split(',').map { |d| d unless d.empty? } end paths.map do |path| path = File.expand_path path raise OptionParser::InvalidArgument unless File.exist? path path end end opt.separator nil opt.separator "Parsing options:" opt.separator nil opt.on("--encoding=ENCODING", "-e", Encoding.list.map { |e| e.name }, "Specifies the output encoding. All files", "read will be converted to this encoding.", "The default encoding is UTF-8.", "--encoding is preferred over --charset") do |value| @encoding = Encoding.find value @charset = @encoding.name # may not be valid value end opt.separator nil opt.on("--locale=NAME", "Specifies the output locale.") do |value| @locale_name = value end opt.on("--locale-data-dir=DIR", "Specifies the directory where locale data live.") do |value| @locale_dir = value end opt.separator nil opt.on("--all", "-a", "Synonym for --visibility=private.") do |value| @visibility = :private end opt.separator nil opt.on("--exclude=PATTERN", "-x", Regexp, "Do not process files or directories", "matching PATTERN.") do |value| @exclude << value end opt.separator nil opt.on("--no-skipping-tests", nil, "Don't skip generating documentation for test and spec files") do |value| @skip_tests = false end opt.separator nil opt.on("--extension=NEW=OLD", "-E", "Treat files ending with .new as if they", "ended with .old. Using '-E cgi=rb' will", "cause xxx.cgi to be parsed as a Ruby file.") do |value| new, old = value.split(/=/, 2) unless new and old then raise OptionParser::InvalidArgument, "Invalid parameter to '-E'" end unless RDoc::Parser.alias_extension old, new then raise OptionParser::InvalidArgument, "Unknown extension .#{old} to -E" end end opt.separator nil opt.on("--[no-]force-update", "-U", "Forces rdoc to scan all sources even if", "no files are newer than the flag file.") do |value| @force_update = value end opt.separator nil opt.on("--pipe", "-p", "Convert RDoc on stdin to HTML") do @pipe = true end opt.separator nil opt.on("--tab-width=WIDTH", "-w", Integer, "Set the width of tab characters.") do |value| raise OptionParser::InvalidArgument, "#{value} is an invalid tab width" if value <= 0 @tab_width = value end opt.separator nil opt.on("--visibility=VISIBILITY", "-V", RDoc::VISIBILITIES + [:nodoc], "Minimum visibility to document a method.", "One of 'public', 'protected' (the default),", "'private' or 'nodoc' (show everything)") do |value| @visibility = value end opt.separator nil markup_formats = RDoc::Text::MARKUP_FORMAT.keys.sort opt.on("--markup=MARKUP", markup_formats, "The markup format for the named files.", "The default is rdoc. Valid values are:", markup_formats.join(', ')) do |value| @markup = value end opt.separator nil opt.on("--root=ROOT", Directory, "Root of the source tree documentation", "will be generated for. Set this when", "building documentation outside the", "source directory. Default is the", "current directory.") do |root| @root = Pathname(root) end opt.separator nil opt.on("--page-dir=DIR", Directory, "Directory where guides, your FAQ or", "other pages not associated with a class", "live. Set this when you don't store", "such files at your project root.", "NOTE: Do not use the same file name in", "the page dir and the root of your project") do |page_dir| @page_dir = page_dir end opt.separator nil opt.separator "Common generator options:" opt.separator nil opt.on("--force-output", "-O", "Forces rdoc to write the output files,", "even if the output directory exists", "and does not seem to have been created", "by rdoc.") do |value| @force_output = value end opt.separator nil generator_text = @generators.keys.map { |name| " #{name}" }.sort opt.on("-f", "--fmt=FORMAT", "--format=FORMAT", @generators.keys, "Set the output formatter. One of:", *generator_text) do |value| check_generator @generator_name = value.downcase setup_generator end opt.separator nil opt.on("--include=DIRECTORIES", "-i", PathArray, "Set (or add to) the list of directories to", "be searched when satisfying :include:", "requests. Can be used more than once.") do |value| @rdoc_include.concat value.map { |dir| dir.strip } end opt.separator nil opt.on("--[no-]coverage-report=[LEVEL]", "--[no-]dcov", "-C", Integer, "Prints a report on undocumented items.", "Does not generate files.") do |value| value = 0 if value.nil? # Integer converts -C to nil @coverage_report = value @force_update = true if value end opt.separator nil opt.on("--output=DIR", "--op", "-o", "Set the output directory.") do |value| @op_dir = value end opt.separator nil opt.on("-d", "Deprecated --diagram option.", "Prevents firing debug mode", "with legacy invocation.") do |value| end opt.separator nil opt.separator 'HTML generator options:' opt.separator nil opt.on("--charset=CHARSET", "-c", "Specifies the output HTML character-set.", "Use --encoding instead of --charset if", "available.") do |value| @charset = value end opt.separator nil opt.on("--hyperlink-all", "-A", "Generate hyperlinks for all words that", "correspond to known methods, even if they", "do not start with '#' or '::' (legacy", "behavior).") do |value| @hyperlink_all = value end opt.separator nil opt.on("--main=NAME", "-m", "NAME will be the initial page displayed.") do |value| @main_page = value end opt.separator nil opt.on("--[no-]line-numbers", "-N", "Include line numbers in the source code.", "By default, only the number of the first", "line is displayed, in a leading comment.") do |value| @line_numbers = value end opt.separator nil opt.on("--show-hash", "-H", "A name of the form #name in a comment is a", "possible hyperlink to an instance method", "name. When displayed, the '#' is removed", "unless this option is specified.") do |value| @show_hash = value end opt.separator nil opt.on("--template=NAME", "-T", Template, "Set the template used when generating", "output. The default depends on the", "formatter used.") do |(template, template_dir)| @template = template @template_dir = template_dir end opt.separator nil opt.on("--template-stylesheets=FILES", PathArray, "Set (or add to) the list of files to", "include with the html template.") do |value| @template_stylesheets.concat value end opt.separator nil opt.on("--title=TITLE", "-t", "Set TITLE as the title for HTML output.") do |value| @title = value end opt.separator nil opt.on("--copy-files=PATH", Path, "Specify a file or directory to copy static", "files from.", "If a file is given it will be copied into", "the output dir. If a directory is given the", "entire directory will be copied.", "You can use this multiple times") do |value| @static_path << value end opt.separator nil opt.on("--webcvs=URL", "-W", "Specify a URL for linking to a web frontend", "to CVS. If the URL contains a '\%s', the", "name of the current file will be", "substituted; if the URL doesn't contain a", "'\%s', the filename will be appended to it.") do |value| @webcvs = value end opt.separator nil opt.separator "ri generator options:" opt.separator nil opt.on("--ri", "-r", "Generate output for use by `ri`. The files", "are stored in the '.rdoc' directory under", "your home directory unless overridden by a", "subsequent --op parameter, so no special", "privileges are needed.") do |value| check_generator @generator_name = "ri" @op_dir ||= RDoc::RI::Paths::HOMEDIR setup_generator end opt.separator nil opt.on("--ri-site", "-R", "Generate output for use by `ri`. The files", "are stored in a site-wide directory,", "making them accessible to others, so", "special privileges are needed.") do |value| check_generator @generator_name = "ri" @op_dir = RDoc::RI::Paths.site_dir setup_generator end opt.separator nil opt.separator "Generic options:" opt.separator nil opt.on("--write-options", "Write .rdoc_options to the current", "directory with the given options. Not all", "options will be used. See RDoc::Options", "for details.") do |value| @write_options = true end opt.separator nil opt.on("--[no-]dry-run", "Don't write any files") do |value| @dry_run = value end opt.separator nil opt.on("-D", "--[no-]debug", "Displays lots on internal stuff.") do |value| $DEBUG_RDOC = value end opt.separator nil opt.on("--[no-]ignore-invalid", "Ignore invalid options and continue", "(default true).") do |value| ignore_invalid = value end opt.separator nil opt.on("--quiet", "-q", "Don't show progress as we parse.") do |value| @verbosity = 0 end opt.separator nil opt.on("--verbose", "-V", "Display extra progress as RDoc parses") do |value| @verbosity = 2 end opt.separator nil opt.on("--version", "-v", "print the version") do puts opt.version exit end opt.separator nil opt.on("--help", "-h", "Display this help") do RDoc::RDoc::GENERATORS.each_key do |generator| setup_generator generator end puts opt.help exit end opt.separator nil end setup_generator 'darkfish' if argv.grep(/\A(-f|--fmt|--format|-r|-R|--ri|--ri-site)\b/).empty? deprecated = [] invalid = [] begin opts.parse! argv rescue OptionParser::ParseError => e if DEPRECATED[e.args.first] then deprecated << e.args.first elsif %w[--format --ri -r --ri-site -R].include? e.args.first then raise else invalid << e.args.join(' ') end retry end unless @generator then @generator = RDoc::Generator::Darkfish @generator_name = 'darkfish' end if @pipe and not argv.empty? then @pipe = false invalid << '-p (with files)' end unless quiet then deprecated.each do |opt| $stderr.puts 'option ' + opt + ' is deprecated: ' + DEPRECATED[opt] end end unless invalid.empty? then invalid = "invalid options: #{invalid.join ', '}" if ignore_invalid then unless quiet then $stderr.puts invalid $stderr.puts '(invalid options are ignored)' end else unless quiet then $stderr.puts opts end $stderr.puts invalid exit 1 end end @files = argv.dup self end ## # Don't display progress as we process the files def quiet @verbosity.zero? end ## # Set quietness to +bool+ def quiet= bool @verbosity = bool ? 0 : 1 end ## # Removes directories from +path+ that are outside the current directory def sanitize_path path require 'pathname' dot = Pathname.new('.').expand_path path.reject do |item| path = Pathname.new(item).expand_path is_reject = nil relative = nil begin relative = path.relative_path_from(dot).to_s rescue ArgumentError # On Windows, sometimes crosses different drive letters. is_reject = true else is_reject = relative.start_with? '..' end is_reject end end ## # Set up an output generator for the named +generator_name+. # # If the found generator responds to :setup_options it will be called with # the options instance. This allows generators to add custom options or set # default options. def setup_generator generator_name = @generator_name @generator = @generators[generator_name] unless @generator then raise OptionParser::InvalidArgument, "Invalid output formatter #{generator_name}" end return if @generator_options.include? @generator @generator_name = generator_name @generator_options << @generator if @generator.respond_to? :setup_options then @option_parser ||= OptionParser.new @generator.setup_options self end end ## # Finds the template dir for +template+ def template_dir_for template template_path = File.join 'rdoc', 'generator', 'template', template $LOAD_PATH.map do |path| File.join File.expand_path(path), template_path end.find do |dir| File.directory? dir end end # Sets the minimum visibility of a documented method. # # Accepts +:public+, +:protected+, +:private+, +:nodoc+, or +:all+. # # When +:all+ is passed, visibility is set to +:private+, similarly to # RDOCOPT="--all", see #visibility for more information. def visibility= visibility case visibility when :all @visibility = :private else @visibility = visibility end end ## # Displays a warning using Kernel#warn if we're being verbose def warn message super message if @verbosity > 1 end ## # Writes the YAML file .rdoc_options to the current directory containing the # parsed options. def write_options RDoc.load_yaml File.open '.rdoc_options', 'w' do |io| io.set_encoding Encoding::UTF_8 io.print to_yaml end end ## # Loads options from .rdoc_options if the file exists, otherwise creates a # new RDoc::Options instance. def self.load_options options_file = File.expand_path '.rdoc_options' return RDoc::Options.new unless File.exist? options_file RDoc.load_yaml begin options = YAML.safe_load File.read('.rdoc_options'), permitted_classes: [RDoc::Options, Symbol] rescue Psych::SyntaxError raise RDoc::Error, "#{options_file} is not a valid rdoc options file" end return RDoc::Options.new unless options # Allow empty file. raise RDoc::Error, "#{options_file} is not a valid rdoc options file" unless RDoc::Options === options or Hash === options if Hash === options # Override the default values with the contents of YAML file. options = RDoc::Options.new options end options end end PK!ѓ#R))stats.rbnu[# frozen_string_literal: true ## # RDoc statistics collector which prints a summary and report of a project's # documentation totals. class RDoc::Stats include RDoc::Text ## # Output level for the coverage report attr_reader :coverage_level ## # Count of files parsed during parsing attr_reader :files_so_far ## # Total number of files found attr_reader :num_files ## # Creates a new Stats that will have +num_files+. +verbosity+ defaults to 1 # which will create an RDoc::Stats::Normal outputter. def initialize store, num_files, verbosity = 1 @num_files = num_files @store = store @coverage_level = 0 @doc_items = nil @files_so_far = 0 @fully_documented = false @num_params = 0 @percent_doc = nil @start = Time.now @undoc_params = 0 @display = case verbosity when 0 then Quiet.new num_files when 1 then Normal.new num_files else Verbose.new num_files end end ## # Records the parsing of an alias +as+. def add_alias as @display.print_alias as end ## # Records the parsing of an attribute +attribute+ def add_attribute attribute @display.print_attribute attribute end ## # Records the parsing of a class +klass+ def add_class klass @display.print_class klass end ## # Records the parsing of +constant+ def add_constant constant @display.print_constant constant end ## # Records the parsing of +file+ def add_file(file) @files_so_far += 1 @display.print_file @files_so_far, file end ## # Records the parsing of +method+ def add_method(method) @display.print_method method end ## # Records the parsing of a module +mod+ def add_module(mod) @display.print_module mod end ## # Call this to mark the beginning of parsing for display purposes def begin_adding @display.begin_adding end ## # Calculates documentation totals and percentages for classes, modules, # constants, attributes and methods. def calculate return if @doc_items ucm = @store.unique_classes_and_modules classes = @store.unique_classes.reject { |cm| cm.full_name == 'Object' } constants = [] ucm.each { |cm| constants.concat cm.constants } methods = [] ucm.each { |cm| methods.concat cm.method_list } attributes = [] ucm.each { |cm| attributes.concat cm.attributes } @num_attributes, @undoc_attributes = doc_stats attributes @num_classes, @undoc_classes = doc_stats classes @num_constants, @undoc_constants = doc_stats constants @num_methods, @undoc_methods = doc_stats methods @num_modules, @undoc_modules = doc_stats @store.unique_modules @num_items = @num_attributes + @num_classes + @num_constants + @num_methods + @num_modules + @num_params @undoc_items = @undoc_attributes + @undoc_classes + @undoc_constants + @undoc_methods + @undoc_modules + @undoc_params @doc_items = @num_items - @undoc_items end ## # Sets coverage report level. Accepted values are: # # false or nil:: No report # 0:: Classes, modules, constants, attributes, methods # 1:: Level 0 + method parameters def coverage_level= level level = -1 unless level @coverage_level = level end ## # Returns the length and number of undocumented items in +collection+. def doc_stats collection visible = collection.select { |item| item.display? } [visible.length, visible.count { |item| not item.documented? }] end ## # Call this to mark the end of parsing for display purposes def done_adding @display.done_adding end ## # The documentation status of this project. +true+ when 100%, +false+ when # less than 100% and +nil+ when unknown. # # Set by calling #calculate def fully_documented? @fully_documented end ## # A report that says you did a great job! def great_job report = RDoc::Markup::Document.new report << RDoc::Markup::Paragraph.new('100% documentation!') report << RDoc::Markup::Paragraph.new('Great Job!') report end ## # Calculates the percentage of items documented. def percent_doc return @percent_doc if @percent_doc @fully_documented = (@num_items - @doc_items) == 0 @percent_doc = @doc_items.to_f / @num_items * 100 if @num_items.nonzero? @percent_doc ||= 0 @percent_doc end ## # Returns a report on which items are not documented def report if @coverage_level > 0 then extend RDoc::Text end if @coverage_level.zero? then calculate return great_job if @num_items == @doc_items end ucm = @store.unique_classes_and_modules report = RDoc::Markup::Document.new report << RDoc::Markup::Paragraph.new('The following items are not documented:') report << RDoc::Markup::BlankLine.new ucm.sort.each do |cm| body = report_class_module(cm) { [ report_constants(cm), report_attributes(cm), report_methods(cm), ].compact } report << body if body end if @coverage_level > 0 then calculate return great_job if @num_items == @doc_items end report end ## # Returns a report on undocumented attributes in ClassModule +cm+ def report_attributes cm return if cm.attributes.empty? report = [] cm.each_attribute do |attr| next if attr.documented? line = attr.line ? ":#{attr.line}" : nil report << " #{attr.definition} :#{attr.name} # in file #{attr.file.full_name}#{line}\n" report << "\n" end report end ## # Returns a report on undocumented items in ClassModule +cm+ def report_class_module cm return if cm.fully_documented? and @coverage_level.zero? return unless cm.display? report = RDoc::Markup::Document.new if cm.in_files.empty? then report << RDoc::Markup::Paragraph.new("#{cm.definition} is referenced but empty.") report << RDoc::Markup::Paragraph.new("It probably came from another project. I'm sorry I'm holding it against you.") return report elsif cm.documented? then documented = true klass = RDoc::Markup::Verbatim.new("#{cm.definition} # is documented\n") else report << RDoc::Markup::Paragraph.new('In files:') list = RDoc::Markup::List.new :BULLET cm.in_files.each do |file| para = RDoc::Markup::Paragraph.new file.full_name list << RDoc::Markup::ListItem.new(nil, para) end report << list report << RDoc::Markup::BlankLine.new klass = RDoc::Markup::Verbatim.new("#{cm.definition}\n") end klass << "\n" body = yield.flatten # HACK remove #flatten if body.empty? then return if documented klass.parts.pop else klass.parts.concat body end klass << "end\n" report << klass report end ## # Returns a report on undocumented constants in ClassModule +cm+ def report_constants cm return if cm.constants.empty? report = [] cm.each_constant do |constant| # TODO constant aliases are listed in the summary but not reported # figure out what to do here next if constant.documented? || constant.is_alias_for line = constant.line ? ":#{constant.line}" : line report << " # in file #{constant.file.full_name}#{line}\n" report << " #{constant.name} = nil\n" report << "\n" end report end ## # Returns a report on undocumented methods in ClassModule +cm+ def report_methods cm return if cm.method_list.empty? report = [] cm.each_method do |method| next if method.documented? and @coverage_level.zero? if @coverage_level > 0 then params, undoc = undoc_params method @num_params += params unless undoc.empty? then @undoc_params += undoc.length undoc = undoc.map do |param| "+#{param}+" end param_report = " # #{undoc.join ', '} is not documented\n" end end next if method.documented? and not param_report line = method.line ? ":#{method.line}" : nil scope = method.singleton ? 'self.' : nil report << " # in file #{method.file.full_name}#{line}\n" report << param_report if param_report report << " def #{scope}#{method.name}#{method.params}; end\n" report << "\n" end report end ## # Returns a summary of the collected statistics. def summary calculate num_width = [@num_files, @num_items].max.to_s.length undoc_width = [ @undoc_attributes, @undoc_classes, @undoc_constants, @undoc_items, @undoc_methods, @undoc_modules, @undoc_params, ].max.to_s.length report = RDoc::Markup::Verbatim.new report << "Files: %*d\n" % [num_width, @num_files] report << "\n" report << "Classes: %*d (%*d undocumented)\n" % [ num_width, @num_classes, undoc_width, @undoc_classes] report << "Modules: %*d (%*d undocumented)\n" % [ num_width, @num_modules, undoc_width, @undoc_modules] report << "Constants: %*d (%*d undocumented)\n" % [ num_width, @num_constants, undoc_width, @undoc_constants] report << "Attributes: %*d (%*d undocumented)\n" % [ num_width, @num_attributes, undoc_width, @undoc_attributes] report << "Methods: %*d (%*d undocumented)\n" % [ num_width, @num_methods, undoc_width, @undoc_methods] report << "Parameters: %*d (%*d undocumented)\n" % [ num_width, @num_params, undoc_width, @undoc_params] if @coverage_level > 0 report << "\n" report << "Total: %*d (%*d undocumented)\n" % [ num_width, @num_items, undoc_width, @undoc_items] report << "%6.2f%% documented\n" % percent_doc report << "\n" report << "Elapsed: %0.1fs\n" % (Time.now - @start) RDoc::Markup::Document.new report end ## # Determines which parameters in +method+ were not documented. Returns a # total parameter count and an Array of undocumented methods. def undoc_params method @formatter ||= RDoc::Markup::ToTtOnly.new params = method.param_list params = params.map { |param| param.gsub(/^\*\*?/, '') } return 0, [] if params.empty? document = parse method.comment tts = document.accept @formatter undoc = params - tts [params.length, undoc] end autoload :Quiet, "#{__dir__}/stats/quiet" autoload :Normal, "#{__dir__}/stats/normal" autoload :Verbose, "#{__dir__}/stats/verbose" end PK! i18n.rbnu[# frozen_string_literal: true ## # This module provides i18n related features. module RDoc::I18n autoload :Locale, "#{__dir__}/i18n/locale" require_relative 'i18n/text' end PK!&“ require.rbnu[# 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_file_name, ] 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 PK!  mixin.rbnu[# 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 PK!ٔyy context.rbnu[# 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.rdoc.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 ## # Is part of this thing was defined in +file+? def defined_in?(file) @in_files.include?(file) 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 attributes def each_attribute # :yields: attribute @attributes.each { |a| yield a } end ## # Iterator for classes and modules def each_classmodule(&block) # :yields: module classes_and_modules.sort.each(&block) end ## # Iterator for constants def each_constant # :yields: constant @constants.each {|c| yield c} end ## # Iterator for included modules def each_include # :yields: include @includes.each do |i| yield i end end ## # Iterator for extension modules def each_extend # :yields: extend @extends.each do |e| yield e end 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 a file with +name+ in this context def find_file_named name @store.find_file_named name 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 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(prefix) 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 PK!n"generator/pot/message_extractor.rbnu[# 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.each_constant do |constant| extract_text(constant.comment, constant.full_name) end klass.each_attribute 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 PK!jl{ generator/pot/po_entry.rbnu[# 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 valus 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 PK!generator/pot/po.rbnu[# 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 PK!&generator/pot.rbnu[# 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 def class_dir nil 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 PK!r .generator/template/json_index/js/navigation.jsnu[/* * Navigation allows movement using the arrow keys through the search results. * * When using this library you will need to set scrollIntoView to the * appropriate function for your layout. Use scrollInWindow if the container * is not scrollable and scrollInElement if the container is a separate * scrolling region. */ Navigation = new function() { this.initNavigation = function() { var _this = this; document.addEventListener('keydown', function(e) { _this.onkeydown(e); }); this.navigationActive = true; } this.setNavigationActive = function(state) { this.navigationActive = state; } this.onkeydown = function(e) { if (!this.navigationActive) return; switch(e.keyCode) { case 37: //Event.KEY_LEFT: if (this.moveLeft()) e.preventDefault(); break; case 38: //Event.KEY_UP: if (e.keyCode == 38 || e.ctrlKey) { if (this.moveUp()) e.preventDefault(); } break; case 39: //Event.KEY_RIGHT: if (this.moveRight()) e.preventDefault(); break; case 40: //Event.KEY_DOWN: if (e.keyCode == 40 || e.ctrlKey) { if (this.moveDown()) e.preventDefault(); } break; case 13: //Event.KEY_RETURN: if (this.current) e.preventDefault(); this.select(this.current); break; } if (e.ctrlKey && e.shiftKey) this.select(this.current); } this.moveRight = function() { } this.moveLeft = function() { } this.move = function(isDown) { } this.moveUp = function() { return this.move(false); } this.moveDown = function() { return this.move(true); } /* * Scrolls to the given element in the scrollable element view. */ this.scrollInElement = function(element, view) { var offset, viewHeight, viewScroll, height; offset = element.offsetTop; height = element.offsetHeight; viewHeight = view.offsetHeight; viewScroll = view.scrollTop; if (offset - viewScroll + height > viewHeight) { view.scrollTop = offset - viewHeight + height; } if (offset < viewScroll) { view.scrollTop = offset; } } /* * Scrolls to the given element in the window. The second argument is * ignored */ this.scrollInWindow = function(element, ignored) { var offset, viewHeight, viewScroll, height; offset = element.offsetTop; height = element.offsetHeight; viewHeight = window.innerHeight; viewScroll = window.scrollY; if (offset - viewScroll + height > viewHeight) { window.scrollTo(window.scrollX, offset - viewHeight + height); } if (offset < viewScroll) { window.scrollTo(window.scrollX, offset); } } } PK!P^,generator/template/json_index/js/searcher.jsnu[Searcher = function(data) { this.data = data; this.handlers = []; } Searcher.prototype = new function() { // search is performed in chunks of 1000 for non-blocking user input var CHUNK_SIZE = 1000; // do not try to find more than 100 results var MAX_RESULTS = 100; var huid = 1; var suid = 1; var runs = 0; this.find = function(query) { var queries = splitQuery(query); var regexps = buildRegexps(queries); var highlighters = buildHilighters(queries); var state = { from: 0, pass: 0, limit: MAX_RESULTS, n: suid++}; var _this = this; this.currentSuid = state.n; if (!query) return; var run = function() { // stop current search thread if new search started if (state.n != _this.currentSuid) return; var results = performSearch(_this.data, regexps, queries, highlighters, state); var hasMore = (state.limit > 0 && state.pass < 4); triggerResults.call(_this, results, !hasMore); if (hasMore) { setTimeout(run, 2); } runs++; }; runs = 0; // start search thread run(); } /* ----- Events ------ */ this.ready = function(fn) { fn.huid = huid; this.handlers.push(fn); } /* ----- Utilities ------ */ function splitQuery(query) { return query.split(/(\s+|::?|\(\)?)/).filter(function(string) { return string.match(/\S/); }); } function buildRegexps(queries) { return queries.map(function(query) { return new RegExp(query.replace(/(.)/g, '([$1])([^$1]*?)'), 'i'); }); } function buildHilighters(queries) { return queries.map(function(query) { return query.split('').map(function(l, i) { return '\u0001$' + (i*2+1) + '\u0002$' + (i*2+2); }).join(''); }); } // function longMatchRegexp(index, longIndex, regexps) { // for (var i = regexps.length - 1; i >= 0; i--){ // if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false; // }; // return true; // } /* ----- Mathchers ------ */ /* * This record matches if the index starts with queries[0] and the record * matches all of the regexps */ function matchPassBeginning(index, longIndex, queries, regexps) { if (index.indexOf(queries[0]) != 0) return false; for (var i=1, l = regexps.length; i < l; i++) { if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false; }; return true; } /* * This record matches if the longIndex starts with queries[0] and the * longIndex matches all of the regexps */ function matchPassLongIndex(index, longIndex, queries, regexps) { if (longIndex.indexOf(queries[0]) != 0) return false; for (var i=1, l = regexps.length; i < l; i++) { if (!longIndex.match(regexps[i])) return false; }; return true; } /* * This record matches if the index contains queries[0] and the record * matches all of the regexps */ function matchPassContains(index, longIndex, queries, regexps) { if (index.indexOf(queries[0]) == -1) return false; for (var i=1, l = regexps.length; i < l; i++) { if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false; }; return true; } /* * This record matches if regexps[0] matches the index and the record * matches all of the regexps */ function matchPassRegexp(index, longIndex, queries, regexps) { if (!index.match(regexps[0])) return false; for (var i=1, l = regexps.length; i < l; i++) { if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false; }; return true; } /* ----- Highlighters ------ */ function highlightRegexp(info, queries, regexps, highlighters) { var result = createResult(info); for (var i=0, l = regexps.length; i < l; i++) { result.title = result.title.replace(regexps[i], highlighters[i]); result.namespace = result.namespace.replace(regexps[i], highlighters[i]); }; return result; } function hltSubstring(string, pos, length) { return string.substring(0, pos) + '\u0001' + string.substring(pos, pos + length) + '\u0002' + string.substring(pos + length); } function highlightQuery(info, queries, regexps, highlighters) { var result = createResult(info); var pos = 0; var lcTitle = result.title.toLowerCase(); pos = lcTitle.indexOf(queries[0]); if (pos != -1) { result.title = hltSubstring(result.title, pos, queries[0].length); } result.namespace = result.namespace.replace(regexps[0], highlighters[0]); for (var i=1, l = regexps.length; i < l; i++) { result.title = result.title.replace(regexps[i], highlighters[i]); result.namespace = result.namespace.replace(regexps[i], highlighters[i]); }; return result; } function createResult(info) { var result = {}; result.title = info[0]; result.namespace = info[1]; result.path = info[2]; result.params = info[3]; result.snippet = info[4]; result.badge = info[6]; return result; } /* ----- Searching ------ */ function performSearch(data, regexps, queries, highlighters, state) { var searchIndex = data.searchIndex; var longSearchIndex = data.longSearchIndex; var info = data.info; var result = []; var i = state.from; var l = searchIndex.length; var togo = CHUNK_SIZE; var matchFunc, hltFunc; while (state.pass < 4 && state.limit > 0 && togo > 0) { if (state.pass == 0) { matchFunc = matchPassBeginning; hltFunc = highlightQuery; } else if (state.pass == 1) { matchFunc = matchPassLongIndex; hltFunc = highlightQuery; } else if (state.pass == 2) { matchFunc = matchPassContains; hltFunc = highlightQuery; } else if (state.pass == 3) { matchFunc = matchPassRegexp; hltFunc = highlightRegexp; } for (; togo > 0 && i < l && state.limit > 0; i++, togo--) { if (info[i].n == state.n) continue; if (matchFunc(searchIndex[i], longSearchIndex[i], queries, regexps)) { info[i].n = state.n; result.push(hltFunc(info[i], queries, regexps, highlighters)); state.limit--; } }; if (searchIndex.length <= i) { state.pass++; i = state.from = 0; } else { state.from = i; } } return result; } function triggerResults(results, isLast) { this.handlers.forEach(function(fn) { fn.call(this, results, isLast) }); } } PK!2+D<generator/template/darkfish/_sidebar_table_of_contents.rhtmlnu[<%- 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 -%> PK!>qq0generator/template/darkfish/fonts/Lato-Light.ttfnu[GPOSjNKGSUBV.TLOS/28M`cmapRԟN@cvt &7g|8fpgm zAg gaspgtglyfiS(headDeJ޼6hheaix$hmtxESvJTkern2lllocaKpPP,maxp> R| name UR:post:\cprepx9qH 0JDFLTlatnkernkernJnv$R ^ h B l  & rjZjL*|DV: !.!##L#$4$~%&J'$'()*+f+,6,-.(./t//0:0|2"233T334&4l455b566L667B778889d99:&::;@<=>j?,?@hABCzDEFG*GHfIK V B V#$V&*2497:7<?7DFGHRTmBoByB}BVVVVVVVVBB BBBVK V B V#$V&*2497:7<?7DFGHRTmBoByB}BVVVVVVVVBB BBBV"#&*24FGHRTK V B V#$V&*2497:7<?7DFGHRTmBoByB}BVVVVVVVVBB BBBV- v#&*247L9L:P`Q`R)S`T)U`VDX`YLZt[g\L]mLoLw`yL}L))))))`))))))````))`)LLLLLLL $k7 7 7GG"<#$&*-o24DFGHIJ{PQRSTUVWXY[\]l7mor7tFuFwy{F|7}77G77G7I7 7 7"%$-DFGHJRTVl7mor7t7u7y{7|7}777771#&*24FGHIRTWYZ\moy}i t  y`yt"%#$t&*-824DF`G`H`J[PQR`ST`UVXYZ[\lm`o`rt-u-wy`{-|}`ttttttt````````````t`````yy```t0"%#&*24FGHRTVY\moy}"#&*24FGHRT6V V V"#&*--24789:?DEHIKNPQRSUYZ[\^lmoprtuy{|} 8DFLTlatncase&case,liga2liga8sups>supsD,>B      @ LO,{tu CjqvI,xxDP`KtyPL@Jz  &   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ardeixpkvjsgwl|cnm}byqz`T@ ~1DS[a~    " & 0 : D !"!&"""""""+"H"`"e%&i 1ARZ`x    & 0 9 D !"!&"""""""+"H"`"d%&i{uq[H$I޸ޡޞ:ڜ`T@ ~1DS[a~    " & 0 : D !"!&"""""""+"H"`"e%&i 1ARZ`x    & 0 9 D !"!&"""""""+"H"`"d%&i{uq[H$I޸ޡޞ:ڜ/'37;BK PX@3 `f[[ Q CQ D@4hf[[ Q CQ DY@ ;:$$#,$ +>32#'&>54.#"#"'4632#"&!!7!!332#"&tA1!""'5-PS\88\SP-<""!5) ,@) BQ D   $+#"&/!#"&/  u  ܙ$ܙ$V<6:5BK-PX@(  Y  C Q C D@&  Z  Y  C DY@:98766421/-,(&#"!#!+#"&547!+#"&5<?3#76;>;!323+32%!!^)VV*^R(W*_*_*W(R*REm  &!Fp&!{,F \;FQ@) ! LA*7BK PX@2j  h f_ SC TD@1j  h fk SC TDY@NMCB;965$#$ +.'7632.54>?>;#".'+4.'>H  &4EX8 De>4e_ $ e?  '?]A/_WJ7:mf  $2Tm<P}U,,Lc8LqL&bP'!'#|4QwZEe>K?"!(% (4G[X?-(0K`W'0DX?@<[ [ CSC C SDUS((%"&((($ +#".54>324.#"32>>;+#".54>324.#"32>0Rl<>mP..Pm>>lQ/L#=Q--P<##mP..Pm>>lQ.L#7>;#"&/#".54>7.54>32>7&'CxY5  ":W;*Y-l~OKsG4Z|HGG3^;^s8F}m[&5BkJ(.Ng8 D<*%C\7RVHHI ^[4X?$2aZHmVPVFwX2MrM& 9N/N_n @BQ D $+#"&/  ܙ$(+.54>7yx*Mi@@iM* wyve vuuv eb(+4'&54?'&5476Zyw *Lj@@jL*xyv vuuv {51@.1-,($# BMQE55+5467'7>7./7.=3>?'.'t 4   m,n n-n  m-m n-n m ,@)MYQE +!!#!5!iQNR=I;In@B ?S D"+74632'&5467>7#"&n0'+/(8"  %/U#2;0)URL    '5@$2d)5z@MQE+!!d/zQi"@SD($+74>32#"&i!""'5M""!5@kD""++6;[ 'n')-%I?'@SCSD((($+#".54>324.#"32>?PiiOOiiPdBoRRpBBpRRoBĺWWWWHHGG*@' Bh CR D%+%!47#"/3!!5E  J5'J|"& (iJ2>@;. BhSCQ D-,+)$" 22+2>3!2!5467>54.#"#"&#'>ZQpB1To=E E#co CqW9 0 Kr/_`P~w><8" =rtzENsJ$)Ie<#[b3HU@RD Bhh[SCSDB@;910/.&$HH +2#".'763232>54.#5>54.#"#"/>eQm?+Kf#[b3?^ @[ C D!#+!+#!"&/3467![ Ve UV^4 j /&/@@=-,Bh[Q CSD(#&(#"+#!>32#".'763232>54.#"'!UCx7nq:Nd;j^N  1MiFRi;-[^9H>o|^(?q\p|B#.'$5d]L[3s02@/B[ CSD-+#! +2#".54676;>32>54.#"t[o?E{gcu@T`"TZ4;1ZQVa43]NX`2N7.54>32'2>54.#"2>54.#"DfyD-RqD>`A"9j_^k9"B`>DqR.DyfQ`4Dj<Vi32+>74.#"32>=Wk32#"&4>32#"&!""'5!""'5M""!5D""!5J-H@ (B?K#PX@SCS D@[S DY,*$($+4>32#"&4632'&5467>7#"&!""'50'+/(8"  %/j""!5#2;0)URL    '5@$2 5(+ !'*) A   Ae!@YMQE+!!!!;;,JJ 5(+546767.'&= *(" A   A)!(:9@6BhfSCSD(&#-$+>32#'54>54.#"#"'4>32#"&!DQ`8F|]7/HTI3 A0GSG0*H^3BaB&!""'5 2'*NqFLnS?78")>:3232>54.#"3267632#"$&546$32%2>7.#"XY8R8R6A}t5]%[ %09hP/a}mqd pzvq:e$MG>P3"Zg9(;]W]S'D\5UV.I,7 54&#!yt9'JkE@zqc3`Y3bY*0]U8hXAZd5CkK(K2Rh7|2D@ABhfSCSD,*"  22+%2#".54>32#".#"32>7> (,h{XbeMob/ +=TnF؜WVyLwdV* +/K5g  i+@*- %Y뒖W(:'y @S CS D!(!$+#!!24.#!!2>ybbjRҀcҕRĤbbTT" .@+YQ CQ D +!!!!!"lUSU" (@%YQ C D +!!!#"{gUUv|C4H@E! Bh[SCSD,*%# 44+%2>7!"&=!#".546$32#"'.#"2Ixg]/ 5rYddQvf/  9ahޝUVC+} 8 %:'g  g+?),,0&X쓖X @Y C D+!#!#3!3gggvgZl^@ C D+!#3^ggY'@$Bh CSD#'$+#"&'>7>3232>53;mb-\1  #-LzV-gw|? 0cf"&@#B[ C D'(' +32>7>;#"&'.+#3VT ;S!S  [ff  K X d  V@ CR D+%!!38fWWH %@"Bh C D!5(+>7>;#47+"'#32z  ,GZYF;  y#J (@ C D!+2&53#"'#3 Z1hY2 6yY{'@SCSD((($+#".54>324.#"32>bccbjRҀ~їSS~ҕRĤgg  hgWW씕VVS *@'[S C D !+#!2#%!2>54&#!VfmEu^g7:]q?R4\}J{0T@  BKPX@SCSCD@kSCSDY(((%&+#"&'#".54>324.#"32>+PsHpV ?NccbjRҀ~їSS~ҕRk~-v Fg  hgWW씕VV"2@/ B[S C D" *!+#!2#"&'.#'32>54&#!Vfi8i]Y ;')^g6ƽQeA  >L-TvJW==@:=BhfSCSD;9(&!#!+#".#"#"&'763232>54.54>32~  )FiMMuO)=dd==tlL  (8J`=T[0=dd=6hbnH%-&,Ld7H^B-,5PuWYtCcV,#)#3XyEKaA,*4Qy[Ge=FH#n @Q C D+!#!5nf W0W#@  CSD +%2>53#".53fp;fJ||NjJg;oIG~cku˗VVukc~H@B C D* +3267>;#Q P[ j.46, y' @#B C D,; +32>7>;2>7>;#&'#Ue   eNC\^][u..  u,- y4@B C D(")!+ 32>7>; #"&'+e  beB J ] L T% @ B C D,"+#32>7>;gYZHH? v++ s $@!Q CQ D +!!547!5~ #U%U '@$[OQE !#+!+32>$  $@kD" +32#"&')'n' %"k !@[OQE!"+46;#"&=!!k= s $  @ Bk D,!+3#"&'.'+ <UD    G L3@MQE+!5DDV @kD  +2#"&/ 6  kC'7T@Q-Bh[SC C SD)(/.(7)7"  '' +!"/#".54>754&#"#"/>32%2>7)QXf=3`J-HwuHeF, NmPxO(J:aSH#ͅ?!6H(@,>aD?lP0h(0(NP3_Sx5->$#32#"&'#"32>54&`Bm9oih6hc?9ZXY-XfmPQOzf[VE@ubXX,9@6,BhfSCSD(&#(#"+#".#"32>32#".54>321  #:W>V[01ZNHa?% FXg8_q?5W#q@ BK%PX@CSCS D@!CSC CSDY@## +!"/#"&54>323%267.#"c Bn9oie6`^c?:XXY-ZjmPKHNQ@f[ UF@ubX%0H@EBh[SCSD'&,+&0'0 %% +2#!32>32#".54>"!4.Ti; 14`TKnK, Oao8fxA=skMzY7 ,Pp:oips:!)! 4%GkJG0Z~NPX/n_BK!PX@SCQC D@[SC DY@!$%! +3'&=354>32#"&#"!!nj,PqD? )1S7.54>4.'32>2>54.#"Ao,4]OVF*0ugik6h[2; -GO3]1Rkuv3&A.-W~RLa7@dD#$Ec??dE$$Ed ! &_6HuS.B+.-QC>rX5+I`6Or@9.-()[HuT./9  '1;#,K7 ">V.%B\88]B$$B]88\B%-@*BCSC D##+33>32#4&#"_EnR}R*_bBUe4bW|eXG&@#SCC D +##".54>32_    W!!G'4@1 BSCCSD$"!$%+#"&'76323265#".54>32;Y<. QN    4XA% 0 XQbW!!0@-B[CC D%(%!+3267>;#"&'.+# . TI   S ^-`{ _   @C D+#_Q,8@5+ BCSC D,,##&&! +332>32>32#4&#"#4&#"4 BKU/mATc4JvS,`~u4_I+_toQ6)D1q>Z;1`Z|&KpJ|aV1@.BCSC D#$!+332>32#4&#"4 DoR}R*_bBVi4bW|eXW',@)SCSD'' +2#".54>2>54.#"kt==tkku==ukYY,,YYYY--YIuuHHuuIK=rdcs>>scdr=$D@ABCSCSCD$$&%!+32>32#"&'"32>54&4  Bn9nif6Bc>9YXY-C ZjmPJIg\VF@ubW#D@ABCSCSCD##&#+##"&54>32763267.#"`Bl9oig6 c?6YXY-XfmPNLp]f[RH@ub8@5 BhCSC D#$%!+332>32#".#"20u-L" !0q-yB yY<=@:<BhfSCSD:8'%" #!+#".#"#"&'7>3232>54.54>32 #9S<6Y?#0NchcN0/YSi< &=[C?`@!0NcicN0.UzL[;h4E&/>, ':T5bJ,464@#x@ !BKPX@%jhQCSD@#jh[SDY@ ## +"&5#"&=7>;!!32>32eq  -9%2$4&&upu % d G]);& **3-@*BC CSD$!#+32673#"/#".5逃aC`5 EoS|R*cXVh4bW|@ BC D,!+!#32>7>;T\KH  J H *+ * @#BC D*!); +32>76;2>76;#"'.'+I  '  FFC **-*+(#v@BC D("(!+ 3267>; #"&'+[ $  Xj[  U Z h @BCD,""++32>7>;{D[OO  K I  J: @QCQ D+!!547!5!:d)qK&MK?H3@0*B[[OSG@>;83-+4.#52>54.54>;+";2#".54>):##:)&HiB7!+G3)55)3G+!7BiH&!7)=)7!7hhi8=hM+* 8P19lii5%>./=%5ijl81P8 *+Mh=8ihhQ@QD+3#KKiH5@2B[[OSGEDCB530-3)++546;2>54.54>7.54>54.+"&=323"}&HiB7 !+G3)55)3G+! 7BiH&)9##9)7hhi8=hM+* 8P18lji5%=/.>%5iil91P8 *+Mh=8ihh7!7)=)79@6jk[OSG +2>53#".#"#4>32 %=*N 734632#"&A5'""'5&-PS\88\SP-'5""70;U@R 6&,BjhfkSCTD##'# +.54>?>;#".'>32+M`r>@{s $ W5  !7P8+KfC' EXh: $/Y}N,\a3 JtpM :.!"' 1% bo@i?qCQ:@@=3)Bh[SCS D#&#%&%" +46;4>32#"'.#"!#!>3!#!5>5#C4gfLtW>&  ->V327'#"&''7.732>54.#"($1-n?>m-1$*)$2-n>>m-1$)H+Ic88cJ++Jc88cI+>m-2$*)$2-n?>m-2$)($2-n?8bI++Ib88cJ++JcU( 8@5 B Z Y C D *! +!3267>;!!!!#!5!5!ZZO Z  YPY[n_nhg#!' :v:~:vQ@YQD+3#3#KKKK}kH\A@>HZP=#BhfWSDFD-+(&!#!+#".#"#"&'7>3232>54.5467.54>32>54.'( #9S<8[@#2RhmhR2TR6C/YSi< &>\D>`B"4VmqmV4[g7E.UzL[;'CX`c-G>$=QZ]+YJ 5F'.D7.07F]>S{#&bEApR0C6" % "32#".54>32 W     U,H\@ BKPX@4hf[[ SCSDKPX@4hf[[ SCSD@4hf[[ SCSDYY@ YW*,((#&(%! +632#".54>32#".#"3264>32#".732>54.#"8 ;t`s@Cxc4WJ@ !:[DSa55^MU{S4]dd]44]dc]4;ghhg ;FAvfdwB)! 5bWZa3)Pc^44^cd^44^dhhiij>5&4B@? ,Bh[WSD('.-'4(4$##' +#"&/#".54>754&#"#"/>322>755  15=$!<.*]iDI+;(  0jCeh!81+!*G D$ %9'$A13LO 0-ub"D8' %%(+55   z     { z     S=K PX@_MQE@kMQEY+!#!=R'd)5z@MQE+!!d/zQU/FO:BKPX@/h  [ [SCSDKPX@/h  [ [SCSD@/h  [ [SCSDYY@00OMIG0F0E)!(*,& +4>32#".732>54.#"#32#"&'.#'32654&+U4]dd]44]dc]4;ghhgUu  P nywlvc^44^cd^44^dhhiiyusvd _ @a[\T5%@MQE+!!!%A[D'@WSD((($+4>32#".732>54.#"[/Qn??nQ//Qn??nQ/G$>T00T=$$=T00T>$n>mQ..Qm>>lQ//Ql>0T>$$>T00T?$$?TmP 7@4YYMQE  +!!#!5!!!iQNRRUjInIIa;W-g@ + BK#PX@h[SD@!h[OQEY@(&#! --+2>3!2!546?>54.#"#"&/>V,N9!*8'&1%'4>H |W1I0(E?;*89< #4"G7`fb|=W?@=BKPX@,hh[[SD@1hh[[OSGY@;964.-,+#!?? +2#".'7>3232>54.#5>54.#"#"/>\,L7 H).J5[Y'3?I{W/C+BWTB0M73C$  (%*4!4%1K?"2!A;`f @kD #++7>3 9  0@-BCS CD&$!#+32673#"/#"&'#"&5逃aC`5 Ffb%0cXX\MH+X$6B*@'hiS D+##!#".54>3UVgr==rgR  y8bMP\2o@OSG($+4>32#".$&&$P&&%%V@  BK PX@^jTD@jjTDY@+232654.'73#"&'76(390A'*=Y]1D()N  ,&! `<;0! 5RO BKPX@jjQD@jjMRFY$+37#"/733! :%~ c1W;)@&WSD +2#".54>2654&#"wBjJ''JjBDjK''KjDhiihkii*OoEEoO**OoEEoO*rqqr)'(+7'&547>7.'&54?'&547>7.'&54?      &  %     &  %   q#-O@L! Bh  Z [  CS  D-+(&#"$!" +%3+#5!"/3%37#"/733!47!+>;~m?`C : ( *$ #%~ c1w} dK-=Ge@b710+ Bhh  Z [  CS  DGEB@=<;:9853/.(&#! -- +2>3!2!546?>54.#"#"&/>%37#"/733!+>;f,N9!*8'&1%'4>I| : ( *1I0(E?;*89< #4"@>`f%~ c1b dSqPU_]@N  $SBK PX@B h  h  [[ \ S CS DK PX@B h  h  [[ \ SCS DK PX@B h  h  [[ \ S CS D@B h  h  [[ \ SCS DYYY@!_]ZXUTKHEC=<;:20)' PP!"+%3+#5!"/32#".'7>3232>54.#5>54.#"#*.'>47!+>;~m?`CZ,L7 H).J5[Y'3>J { ( *$ /C+BWTB0M73C$  (%*4!4%1K?"2!G5`f} d*);5@2BhfSCTD('#-$+#".54>?332>324>32#"&DQ`8E}]70GTJ3 A0GTG0*H^3E_@$ !""'52')MoGLkM924#*<45E]B6U;#+#O""!5&$ [&$ [&$ `&$`&$ `&$`4@1YYQ CS D" +!!!!!!!+!HjK8 O i USUc7.|Oh@e<B M Bhf hSCSC S  DKIA@:820(&!OO +232654.'7.54>32#".#"32>7>32#"&'76(390A'$ZeMob/ +=TnF؜WVyLwdV*  (,eyUY]1D()N  ,&! sn i+@*- %Y뒖W(:'+.J5K<;0! "&( Z"&( Z"&( _"&( _&, N&, E&, N&, 1!,@)YS CS D!%(!+3!2#!#%4.#!!!!2>1bbRҀclҕRbbT@T&1{&2 {&2 {&2 {&2{&2 D  (+  ' 7 t34u5pn 4t4vp6o{!-9b@ 21&%BKPX@kCSCSD@jkSCSDY**%(%$+#"&'+7&54>327>;.#"4&'32>bsQ ,lwcySo 7eo$^UGj~їSrVNEdҕRĤg=9` hC?`갠R954&#!VffEu^g7]q?R4\}J'J>@;BhSC CSDED?='%" JJ+2#"&'7>3232>54.54>54.#"#4>UZ./GRG/!7EIE7!2Z~Me< %\G87:%$1$!):DS8I?*+X^eo;kC&DCkC&DvkC&DkCi&DkCW&DjkC&DkBR]@:@BK1PX@5hh  [ S C SD@?hh  [ S CSC SDY@&TSYXS]T]NLDC><7520-,$" BB+2#!32>32#"&'#".54>754&#"#"&/>32>32>5"!4.K`7 l0X|LGdD& JZe4/Uly7?lP.HwuHeF, Mk~/ͅ?!32#".#"32>32#"&'76(390A'%Wg8V[01ZNHa?% -jY]1D()N  ,&! vKsrK>5" =reio:"(" :NO<;0! X&HCX&HvX&HXW&Hj"V&C&v&W&jY}6J6@3<2B65@[SD87B@7J8J.,$"+&54?.'.546?7#".54>32.'2>7.#" ~327>;.#"2>54'h<>=tklQ !&DF=ukX7W 2/0-vKY[.iYZ.P WiCvuHOmCuI1-th9*,?s>rds]E&XC&Xv&XW&Xj&\v!@@=BCSCSCD!!&#+3>32#"&'"32>54&_Bm9nif6Bc>9YXY-XgmPNLg\VF@ubW&\jc&/O@L,BAhZ C CSD('#!&& +2#"&54>7&'!+3"32>!.'F T/L^'1INCfC 23&@2&z"KB92*e y/A'05 ++kBRn@k-H 6Bh h  [SC SCSDDCJICRDR?=1/*(%# BB +2#"&54>7&/#".54>754&#"#"&/>3232>2>7 T/L^)4 )QXf=3`J-HwuHeF, NmPxO(.(@2&:aSH#ͅ?!6H"KB ;3+ (@,>aD?lP0h(0( NP3_Sx "-705 (->$#7!!!!!!#32>$ T/L^&1RPl[.(@2&"KB82+USU "-705 XCNg@d2Bh h  [  SCSCSDEDJIDNEN@>0.+)$"CC +2#"&54>7"#".54>32#!32>3232>"!4. T/L^!+ fxA=sjTi; 14`TKnK, 7EP*,&@2&MzY7 ,Pp"KB4/)GkJ:oips:!)! *" ",505 0Z~NPX/@C D+#_:#@  B CR D+%!!54?3c rf? WKeB ]9#@  BC D+7#54?[ _Y2 TZ4Tv&1 &Qv{7 4@  BKPX@+YSCQ C S DK%PX@)YSCQ C S DK)PX@3YSCQ C Q C SD@1YSCQ CQ C SDYYY@ 1/%(% +!!!!!#".54>32!4.#"32>7l%k]ߠYY߇]k%EJsrKKrsJ2SUNRY/f  h0ZRM=XX씕WWWW2FQa@^. Bh  [ S C SDHG43MLGQHQ><3F4F,*"  22+2#!32>32#"&'#".54>32>2>54.#""!4.K`7 l0Y|LCcE) JZe4,*Ĕbm::mc*E^xZR{R))R{RS|S))S|?HsR1W(Ie>scdr=n4^RU]1W&6  Y&VvW&6Y&V&< 4s&= hJ:&]vs&=kJ:&]s&=kJ:&]v#2@/YSCSD##"" +#543>7'&=37>3#"!{` DlX$3`N7 _ض$5`N7 eb\+0 FpR '3FpRG (@Bk D* +#"/&'+73(A CU  ( @Bk D' +32?>;# C AU 5%q5 @W D +".5332>53$B[9E(A00A)E9['DZ2%B22B%2ZD'}@SD($+#".54>32}    F!!xs=K'PX@WSD@[OSGY$&($+4>32#".732654&#"x/?##?//?##?/:@32@@23@$<++<$$;,,;$2@@22@@ +@(B@jSD+2#"&54>732> T/L^-81.(@2&"KB"=6, "-705 &*iQKPX@WS D@[OSGY@ +2673#".#"#4>32+,;%6"!;63*,=&6"";537/$?.!'!9-$?.!'!| #@ SD   #++7>3!+7>3 * R /   .s\BK1PX@SCS D@SC CSDY@!$## ++#!#"&'7632325#5463s_,mi4 $e=nt '" f@MQE+!!fGf@MQE+!!fG!.(+.5467L=&2#!&K&N;3d6;=n(+'&547>54'&547L=&2#&K&N;2e6:=n(+7'&547>54'&547L=&2#&K&N;2e6:=!;)(+.5467.5467L=&2#L=&2#!&K&N;3d6;=&K&N;3d6;=n')(+'&547>54'&547%'&547>54'&547L=&2#JL=&2#&K&N;2e6:=&K&N;2e6:=n')(+7'&547>54'&547%'&547>54'&547L=&2#JL=&2#&K&N;2e6:=&K&N;2e6:=@ BKPX@CCSCDK%PX@ZCCD@`ZCDYY@ #!""+463632>72!#"'!MS  RN     -@  &" BKPX@/  `  [CCSC  DK%PX@-  `Z  [CC  D@/`  `Z  [C  DYY@+)('%#! !"#+7!!5463632>72!!#.'#"'"&5|MS  RN}NR  SM   B  1i|@OSG($+4>32#"..Pj<=lP..Pl=32#"&%4>32#"&%4>32#"&i!""'5!""'5!""'5M""!5'""!5'""!5Wz'0DXlK@H[   [ CSC C  S D}{sqig_]US((%"&((($+#".54>324.#"32>>;+#".54>324.#"32>%#".54>324.#"32>0Rl<>mP..Pm>>lQ/L#=Q--P<##mP..Pm>>lQ.L#mP..Pm>>lQ.L#7.'&54?    &  %   6 @ C D#"+'+>;k ( * doN[@X ; Bh  h [   [SC S  DNMHGFEA?97$##%'$+3>32#".#"!#!!#!32>32#".'#53.547#Zn@m]Q% "1CY:ZqJZ HpZ>_H4$ %$TfxFqT_ҒN,A+#%?zv /2' |~@%+% #.K5Nً;'10HH#C@@ BhS  CS  D##!4% +67>;#7+"'#32###5 9> ?9 WG l,z*E?x;;h}71@.1BSCS D76***+!>54.#"!"&=!5.54>32!#c`r>VooŔV>q` byDe뇇eDxbkOwg~~??~~gwO4\mؖOO؉m\4{.BC@@4Bh[SCSD0/:8/B0B#+(($+>32#".54>32>54&#"#"&'2>7.#"$CCG(W_2GԌQ`5Iq5cVD1K8%  MRoO +GeEbk9(If=# H~6f[rɖV9W;;5- &Gy3cN/IdKvR+ @B CR D+3!7!&'^\M *  ySz!+&M $@!Q CD +##!##5bbRkkRW&@# BQ CQD+!!!!547 &5W{[ ` RR$1. z@MQE+!!=I("@ Bj[ D*# +#"&=!267>;#5:  :O .)%' IJ ';OL@IK-B[  O  SG=<)(GE32>32%2>7.#"!2>54.#"7\NCCN[79hO//Oh97[NCCN\79hO//OhF,KB;;BK,,M:!!:M+M9!!9M+-KB;;BK(BW//VC(+PsGGrP+(CW..WC(+PrGGsP+N&@S--T@&:V78V::V87V:&@T--S@&K)*@'BSCSD!%)U$+>32#"&#"#"&'7>3232>7 :Vo@'9  4XC- ?]xE!A "<`G/ >WU+ +  DgHcZ* '  GqQ/d@a('B[[[ O SG,*%# //  +267#".#"'>32267#".#"'>32 4Xd84ec`.7Wc<4fc_.4Xd84ec`.7Wc<4fc_*-:+/$,$-8-0$,$-:+.$,$-8-/$,$pkK PX@)^_ ZMQE@'jk ZMQEY@  +!3!!!!#!5!7!uGth@vHvThDe JJJPO!@ @MQE+!! ''%v>     ?xIPO!@ @MQE+5467>7.'.=!5! &&& (?    >If"@ BMQE+3 # >7 .'BnBL  N  @@S@CD+3#kaBK!PX@SCQC  D@[SC  DY@!$%! +3'&=354>32#"&#"!#!nj6g_!G +!G`{ 'U\g7 0 R<}"K!PX@SCQC  DK1PX@[SC  D@![CSC  DYY@""A15! +3'&=354>32;#.#"!!nj4d`"IE<H_6w0KvQ+ { 'AXn>nO/Y~NAGR @jD  +2+:  0[ "6M6  @ja  +2#"&'%tG   2E%@OSG&(($+#".54>32#".54632   0!    !1 U5q@MQE+!!Uaq<J @ja #++7>3J  F  <@Bja, +#"&/.'+73?>;# J IZ{{2 (@%jOSG   +"&5332653$|v@R``R@vpfGQQGbt8{@OSG($+#".54>32{  }!@[OSG$&($+4>32#".732654&#"}-="">-->""=-5@32@@23@^";**;"#:**:#2@@22@@*)1@.[OSG +2673#".#"#4>32*,6"5"!<85*+8$4""<84P7+#;- % 8*"<- % j +@(OSG   #++7>3!+7>3 / q  4  m @kD  +2+U  3 #;U< .U_<ʓ^pӡ6z V6:z/VWgjXXb {mndiI?x!kl |x|VY(;{;{W# sXXkIVkDXDWXK:7::W.DW\Y4:#JX?XXiCUXI'MUjjdMUI[mabI:6IWjS*      7|VVVV '1;{;{;{;{;{;{kkkkkkIkXXXXX"0Y::W:W:W:W:Wm:W::::. k|XX*:X9:{W:W\YW\YsJsJsJvI I II5IIxII&I|.:7nnnn`iWkk6Hh{TMTWc(TJ*lIIIIUII I I2II}I*IjIl#`  V B V#$V&*2497:7<?7DFGHRTmBoByB}BVVVVVVVVBB  BBBV V  B  V # $V & * 2 4 97 :7 < ?7 D F G H R T mB oB yB }B V V V V V V V  V  B B B B B V # & * 2 4 F G H R T V  B  V # $V & * 2 4 97 :7 < ?7 D F G H R T mB oB yB }B V V V V V V V  V  B B B B B V   v#&*247L9L:7P`7Q`7R)7S`7T)7U`7VD7X`7YL7Zt7[g7\L7]7mL7oL7w`7yL7}L7777777777777777777777)7)7)7)7)7)7`7)7)7)7)7)7)7`7`7`7`7777)7)7`77)7L7L7L7L7L7L7L78 8888$88888888888979 9 79 79G99G9999"<9#9$9&9*9-o92949D9F9G9H9I9J{9P9Q9R9S9T9U9V9W9X9Y9[9\9]9l79m9o9r79tF9uF9w9y9{F9|79}99999999999999999999999999999999999999999999999997979G97979G999979:7: : 7: 7:::::"%:$:-:D:F:G:H:J:R:T:V:l7:m:o:r7:t7:u7:y:{7:|7:}::::::::::::::::::::::::::::::::::7:7::7:7:::::7:;;#;&;*;2;4;F;G;H;I;R;T;W;Y;Z;\;m;o;y;};;;;;;;;;;;;;;;;;;;;;;;;;;;;;<< t< < <y<`<y<t<<<"%<#<$t<&<*<-8<2<4<D<F`<G`<H`<J[<P<Q<R`<S<T`<U<V<X<Y<Z<[<\<l<m`<o`<r<t-<u-<w<y`<{-<|<}`<t<t<t<t<t<t<t<<<<<<<<<<<<<<<`<`<`<`<`<`<<`<`<`<`<`<`<<<<<t<<<`<`<<<`<`<`<<<y<<<y<`<`<`<<t=="%=#=&=*=2=4=F=G=H=R=T=V=Y=\=m=o=y=}=============================>#>&>*>2>4>F>G>H>R>T>>>>>>>>>>>>>>>>>>>>>>>>?V? V? V??"?#?&?*?--?2?4?7?8?9?:?# #&#n#$"$$%.%d%%&.&t&'0'))r)~)))))*********++T+`+l+x++++,P,\,h,t,,,-P-\-h-t---.x///(/4/@/L/X/d/p/0000&020>011 11$101<1122223<334*4\4h4t5<5556666(646@6L6X6d66777D7n778R88899>9d99::V:;t;;<<= =>=>4>??F?p???@@A^AAB6BxBBCbCCCD D.D\DDDE$EhEE`"/n   ( ( 0% % 4  2( Z 6 J ^ Pl  P  `     0 V d    4n   Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.Lato LightRegulartyPolandLukaszDziedzic: Lato Light: 2013Version 1.105; Western+Polish opensourceLato-LightLato is a trademark of tyPoland Lukasz Dziedzic.Lukasz DziedzicLato is a sanserif typeface family designed in the Summer 2010 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in 2010, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness.http://www.typoland.com/http://www.typoland.com/designers/Lukasz_Dziedzic/Copyright (c) 2013-2013 by tyPoland Lukasz Dziedzic (http://www.typoland.com/) with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1 (http://scripts.sil.org/OFL).http://scripts.sil.org/OFLCopyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.Lato LightRegulartyPolandLukaszDziedzic: Lato Light: 2013Lato-LightVersion 1.105; Western+Polish opensourceLato is a trademark of tyPoland Lukasz Dziedzic.Lukasz DziedzicLato is a sanserif typeface family designed in the Summer 2010 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in 2010, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness.http://www.typoland.com/http://www.typoland.com/designers/Lukasz_Dziedzic/Copyright (c) 2013-2013 by tyPoland Lukasz Dziedzic (http://www.typoland.com/) with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1 (http://scripts.sil.org/OFL).http://scripts.sil.org/OFLLatoLightZD  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#NULLuni00A0uni00ADmacronperiodcenteredAogonekaogonekEogonekeogonekNacutenacuteSacutesacuteZacutezacute Zdotaccent zdotaccentuni02C9EuroDeltauni2669undercommaaccent grave.case dieresis.case macron.case acute.casecircumflex.case caron.case breve.casedotaccent.case ring.case tilde.casehungarumlaut.case caron.saltbKbKVV, `f-, d P&ZE[X!#!X PPX!@Y 8PX!8YY Ead(PX! E 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #B *! C +0%QX`PaRYX#Y! @SX+!@Y#PXeY-,C+C`B-,#B# #Bab`*-, E EcEb`D`-, E +#%` E#a d PX!0PX @YY#PXeY%#aDD`-,EaD- ,` CJPX #BY CJRX #BY- , b c#a C` ` #B#- ,KTXDY$ e#x- ,KQXKSXDY!Y$e#x- , CUX CaB +YC%B %B %B# %PXC`%B #a *!#a #a *!C`%B%a *!Y CG CG`b EcEb`#DC>C`B-,ETX #B `a  BB` +m+"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-,+ETX #B `a  BB` +m+"Y-,+-,+-,+-,+-,+-,+- ,+-!,+-",+-#, +-$, <`-%, ` ` C#`C%a`$*!-&,%+%*-', G EcEb`#a8# UX G EcEb`#a8!Y-(,ETX'*0"Y-),+ETX'*0"Y-*, 5`-+,EcEb+EcEb+D>#8**-,, < G EcEb`Ca8--,.<-., < G EcEb`CaCc8-/,% . G#B%IG#G#a Xb!Y#B.*-0,%%G#G#aE+e.# <8-1,%% .G#G#a #BE+ `PX @QX  &YBB# C #G#G#a#F`Cb` + a C`d#CadPXCaC`Y%ba# &#Fa8#CF%CG#G#a` Cb`# +#C`+%a%b&a %`d#%`dPX!#!Y# &#Fa8Y-2, & .G#G#a#<8-3, #B F#G+#a8-4,%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%aEc# Xb!YcEb`#.# <8#!Y-5, C .G#G#a ` `fb# <8-6,# .F%FRX ,1+!# <#B#8&+C.&+-?, G#B.,*-@, G#B.,*-A,-*-B,/*-C,E# . F#a8&+-D,#BC+-E,<+-F,<+-G,<+-H,<+-I,=+-J,=+-K,=+-L,=+-M,9+-N,9+-O,9+-P,9+-Q,;+-R,;+-S,;+-T,;+-U,>+-V,>+-W,>+-X,>+-Y,:+-Z,:+-[,:+-\,:+-],2+.&+-^,2+6+-_,2+7+-`,2+8+-a,3+.&+-b,3+6+-c,3+7+-d,3+8+-e,4+.&+-f,4+6+-g,4+7+-h,4+8+-i,5+.&+-j,5+6+-k,5+7+-l,5+8+-m,+e$Px0-KKRXYc #D#pE (`f UX%aEc#b#D * **Y( ERD *D$QX@XD&QXXDYYYYDPK!䍒TtTt8generator/template/darkfish/fonts/Lato-RegularItalic.ttfnu[ DSIGtLGPOS,HPGSUBV.TI|OS/2ٮJ`cmapRԟJcvt 'i8fpgm zAj4 gaspiglyfmrO>headd6hhea`L$hmtx4WpTkern@BglocaE/R,maxpC T nameUTpost:]fXprepx9s 0JDFLTlatnkernkernGrTv   V 8,^$^ 0 DJJJL F !z" ##P#$4$~%x&&'()*++,J,-n../$/V///1242n2233V3344J4445567778~88:;";;<=2>,?&?@ABC8CDE.F(> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U-#&*24DFGHRTkp> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U0 ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;;& ^^$7A9;<@=?lr|@@^^^0 ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;;q6 6 6AA":#$&*-i24DFGHPQRSTUVXYZ\]kl6mopr6tPuPwy{P|6}66A66AA$ $79;<=?@`lr|:J J J#&*->247|89: |LL|"$|-:DFGHPQRSTUXw||||||||LLL| $+  #&*24IWYZ\klmopry|}3 ;#&*24789J:h<,?JY|Z\|klm;o;prt,u,y;{,|};,||,;;;;;$ $79;<=?@`lr|/ vCCv$v-JDFGHRTvvvvvvvvCCCv$ $79;<=?@`lr|#&*2478kpf |LLL|ff"'#$|&*-824D/F/G/H/JEPfQfR/SfT/UfVJXfYWZ[Z\L]_kmLoLpwfyL}L|||||||/////////////f//////ffffWW|///f/JJ___LLLLLLLL| $q6 6 6AA":#$&*-i24DFGHPQRSTUVXYZ\]kl6mopr6tPuPwy{P|6}66A66AAN: : :$-DFGHJPQRSTUVXl:r:t<u<w{<|:::::+  #&*24IWYZ\klmopry|}m7 r 7 7'J'r"2#$r&*-824DAFAGAHAJWPQRASTAUVAX]kl7mJoJpr7t>u>wyJ{>|7}JrrrrrrrAAAAAAAAAAAAAAAAAAArAAAAAAJJ77'77'J'JJr"##&*24kmopy}-#&*24DFGHRTkp:J J J#&*->247|89: UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U& ^^$7A9;<@=?lr|@@^^^& ^^$7A9;<@=?lr|@@^^^$ $79;<=?@`lr|> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U TT$T9:::<(?:TTTTTTT(T(T TT$T9:::<(?:TTTTTTT(T(T& ^^$7A9;<@=?lr|@@^^^ TT$T9:::<(?:TTTTTTT(T(T> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U& ^^$7A9;<@=?lr|@@^^^:J J J#&*->247|89:247|89:247|89:247|89:247|89:247|89:u>wyJ{>|7}JrrrrrrrAAAAAAAAAAAAAAAAAAArAAAAAAJJ77'77'J'JJr$ $79;<=?@`lr| @[`lr| @[`lr| @[`lr| @[`lr| @[`lr| Y\lrtu{| @[`lr| @[`lr| @[`lr| @[`lr| @[`lr| @[`lr|. rr$DFGHRTrrr @[`lr|. rr$DFGHRTrrr:J J J#&*->247|89:u>wyJ{>|7}JrrrrrrrAAAAAAAAAAAAAAAAAAArAAAAAAJJ77'77'J'JJr"##&*24kmopy}"##&*24kmopy}"##&*24kmopy}& ^^$7A9;<@=?lr|@@^^^& ^^$7A9;<@=?lr|@@^^^> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U0 ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;;> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U0 ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;;& ^^$7A9;<@=?lr|@@^^^0 ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;;& ^^$7A9;<@=?lr|@@^^^& ^^$7A9;<@=?lr|@@^^^> UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U:J J J#&*->247|89:?EHIKNPQRSUYZ[\^klmoprtuy{|} 8DFLTlatncase&case,liga2liga8sups>supsD,>B      @ LO,{tu CjqvIxxtP`KtyPLJz  &   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ardeixpkvjsgwl|cnm}byqz`T@ ~1DS[a~    " & 0 : D !"!&"""""""+"H"`"e%&i 1ARZ`x    & 0 9 D !"!&"""""""+"H"`"d%&i{uq[H$I޸ޡޞ:ڜ`T@ ~1DS[a~    " & 0 : D !"!&"""""""+"H"`"e%&i 1ARZ`x    & 0 9 D !"!&"""""""+"H"`"d%&i{uq[H$I޸ޡޞ:ڜ-(8<@J@GBhf[[ Q CQ D@?($#-$ +>32#'.54>54&#"#"'4632#"&!!7!!9DO.?gI)-60#z -5-I9)8(  c>0((0>22cu&#@[87P;+&%ia /(&.8'3</@)(?g6, !&@#Q CSD +#>74>32#".F uF!-."".-!-UV\44\VU->."".-""- *@' BQ D   $+#"&=!#"&=$"%$"%ߛ""!ߛ""!6<@H@E  Y  C Q C D@?>=<<6431.-(&##!#!+#"&547#+#"546?3#7>;>;3323+32%3# Nqt 0M+j'&v -NMv&%jjX ]#( 7KGk X G 7KGbf8CN@J) ?BAK PX@$jhfkCDK PX@$jhfkCD@$jhfkCDYY#'#%+.'7632.54>?>;#".'+4.'>w?=+A\Dg>w]9B|o@&g30 %6I2]@~c>Fu"@":N,`JsP)5H)WHkG" aKN&1/1KoRSxL Q;@"!2IlO_S,A0#2Oh*?1%-DUZ'1EYKPX@'[ [SC S DK PX@+[ [SC C SD@/[ [ CSC C SDYY@ VT((%#&((($ +#".54>324.#"32>>;+#".54>324.#"32>;`{A8^C%6]}F8^C&$1(G4$1'G5w | ~:`|A8]C%6]}F8]D%$1(G5$1'G6xcj7)MoFck8)NpH2H."JsQ1E-!GqU  ci7)MnFcl8)NpH2G."JrQ1F-!Hr9BN@;LK.&BKPX@*hSCS CS D@(hSCS CSDY@IG20)'#! BB+2#"'.#">7>;#"./#".54>7.54>3267FrR-e)<)3R; /2B)6w[G `^Rb65]}H'%9iq#=T1_Fsr,Nj>!8-&C[49x?gBGs` zWf1[QOu\ B?Rj>8W<VF> @ BQ D $+#"&=$"%ߛ""!zS  (+.547* Q*;& UuG JrN)JC .VS / r  (+4.'&546? '.547>9) R);& TuF IsN)1IC /WT. ra6C@0,+'$# BKPX@ kD@ jaY@ 66+7>7'767&/7&546?3>?'.'i !$$$3T  # 2a!  dIefIe  ! dIe fHd  sA .@+jkMRF +!!#!7!5f55i6SQ2$@ ?S D"+74632'&54>7#"&2A6.1F- *' 4A{/B'3-a_Z&  &5E*Ea<@MQE+!!s8-'@SD($+74>32#".-"--""--"n."".-""-. @kD#"++>;]:I4 I "!Oj',@)SCSD'' +2#".54>2>54.#"_sAb~`sAb TqB-Le8TqB-LeIےkIۓJkYxj0Yxi0*@' Bh CR D$+7!7#"&/3!!6{,֌M Kq/J4;@80 BhSCQ D-+'% 44+2>3!2!7>7>54.#"#"&/>Sf99bJQ)R&HIrO)#>U2p% # Wc/ZR[~Cx  "5;)AusxE6R6ufbf4]XCU@R? Bhh[SCSD<:64.-,+#!CC +2#".'763232>54.#7>54.#"#"&/>Tb6*MmCz{VjdjBP,B\ARW.Nf">T2r& # Xc.UxIOyZ;#pl{B.\_:W:8Zr;0Q;"{5P5vebf4-f'@$ B\ C D!#+3+#!"&/3>7!./"+ b{W79DF.@@=,+Bh[Q CSD(#&(""+#!632#".'763232>54.#"'!<379so\ii4]u?p_N=/C_CSd7$HnK2sDgM$/9dQ~͐O)6J%8eV9]C$h022@/B[ CSD/-%# +2#".54>7>;>32>54.#"Oe:Tvbl99W<3.%7$Dd@Oa6'Ge>O^5l2`WoPwy}E3,$)!;cH(5^L=cE%8_~$@!BQ C D$'++>7!"&=7  'D-+)uR>3GD@AB[SCSD54! ?=4G5G+) 3!3 +".5467.54>32'2>54.#"2>54.#"cr>aaHiZe6t|QcN~Z0-Lc5Bz_9$FdQqG :X;HoL'9Y3^Q)&bXq@4[{F-#uiw?.RtF@Z9$LwS5W?#4Sf3-N;"-Lh:+P=%w12@/B[SC D.,&$ +".54>32+>74.#"32>5K`7Rp^h8;T6c0.=P%D_:I{Z3xO~Y0M0\TiN;jXH}vvB<6-/:_D%2Y{Ju5Zv-';K$PX@SCSD@[SDY((($+74>32#".4>32#".-"--""--"d"--""--"n."".-""- ."".-""-.,D ?K$PX@SCS D@[S DY@ )'"+74632'&54>7#"&4>32#"..A6.1F- *' 4Ai"--""--"{/B'3-a_Z&  &5E*E."".-""-W(+6#/+-   '0!@YMQE+!!!!Z:X=Ѓ}X(+ 7>7%>7.'%.54>7/+Z|o   '0n%95@2BhfSCSD(&#*$+>32#7>54&#"#"'4>32#".!KWc8FqP*/HWO= %w 5LWI1_Q8R;'  !-."".-!4(*Je;TvW?;@+0JA>H[=NZ$."".-""-MMTdf@c [ <Bh[  [  [OSGVU^\UdVdLJ@>9731)'TT +%"&'#".54>3232>54.#"3267>32#".54>32%2>7&#"FR?H0G. ?[wT?[)!3aK.DzelPvL  k_0 3HR_ɥu@O؊םYu3WC( GrI9H $@!BZ C D# +!#"&'!+3!.'N %> ^zQB&&Cae*=@: B[S CS D*(" !+3!2# !2>54&#%32>54&+aph2%JoJGy?OxP(QyQ(|-SwI@tbLpcxB*NnE_q+MlAggd/D@A BhfSCSD'%"  //+%2>32#".546$32#".#"BfN7) A^̍KtL|fS$@(EmWtʔU:g ' Qfq\䉻6{2F+N (/(]o{Ba= @S CS D!(!$+#!!24.#!!2>=qՔP7g]Ό2xƎO1vZlyA[aA (@%YQ CQ D+!!!!!!.<=uϱ/aA "@YQ C D+!!!#!.?L/d%:G@D& Bh[SCSD20+)" ::+%2>7#"&50>17!#".546$32#"'.#"4ZOI$' C6sRӖQsSnY%< 5KjK{͓R;l D O':']芹3z2D(N  )%^q~CaE @Z C D+!#!#3!3QEPOOr}@ C D+!#3=QKPXBBYKPX@ CSD@h CSDY#%"+#"&'7>3232>736^0 !+4\J3 um"N~\r% &@# B\ C D'(% +3267>;#".'.+#3B#-,%# '+QQ"  #Y  <naf@ CR D+%!!3/7av"&@#Bh C D!6(+67>;#>7+"'#324 3 /.['*' g#.~++. {aE@B C D!+2>73#"&'#3r j^ ` )gHd)@SCSD(((&+#".546$324.#"32>4_kӕOrӕO8g]vƎP8g]xƎO2zڹh8^扷3|_m|D_m|C^ri/@,[S C D !+#!2# 32>54.#nBrm6JυtJUX."DhE6dVqM4]L:\A#d0P BKPX@SCSCD@kSCSDY(((%&+#"&'#".546$324.#"32>3^R!"56q<ӕOrӕO8g]vƎP8g]xƎO2yظ4w^扷3|_m|D_m|C^rU#7@4B[S C D#",!+#!2#"'.# 32>54&#vJyrm54bW 51 "%/DUY-Y0YNWwS&(0WwGms ==@:=BhfSCSD;9(&#!#"+#".#"#"&'7>3232>54.54>32 &;T?@dE$0NeheN0FtAB,DdKEoM*0NcicN0@xln9#)#(E\54G3')2JhJfPeVY -7-,NmB7I2%&0JlOX|JTI{ @Q C D+!#!7YW$#@  CSD +%2>73#".5473vPeA kjc{ow>jk'Ko>mZi{ӛXHj-/i&K|Z1|W@B C D, +32>7>;#|%7 M**L!g,!@' B C D,> +32>7>;2>7>;#.'#  $+  ' / ( < : :gO&&@B C D'"(!+ 3267>; #"&'+ l  z Q$l q $y@ B C D,"+#32>7>;GG  } !=;^44>$@!Q CQ D+!!7>7!7 " l7< l; !W'@$[OQE!#+!+32!WřC  lq @kD# +32#"&'lI +iH2"9" )'@$ B[OQE!#+!!7>;#"&57X ĘC80@ Bk D+!+3#"&'.'+>rg z`+,+X@MQE+!7+ttM @kD  +2#"&' kc  0+^@ BK"PX@SCS D@SC CSDY@ $!++*' +!#"&57#".54>322>7.#"0\#$S]f732#"&'#"32>54&OX&X`h6"?YmFQ* 0b[P &j74\L<)V4=eF'R_6D?Au32#".#"32>3234]^e:X[/Mrd38 +A3E{\58Q6-F6)!,9L-eG'!65*s@ BK"PX@CSCS D@!CSC CSDY@$"** +!"&57#"&54>323%2>7.#"#&Zck7"?YmFJ{+E90a[O!&j6OY0V$AjK)R^6:6-?;iV 5,^Yw};q*9b@ 0BK PX@hSCSD@hSCSDY@ ,++9,9*&%*+32>32#".54>32%">54.q6uv0K;-& ,3afo@W`4!?[uQMpH#?jR:d #8BoYB  #75K2:k^NxW2,DRB4[{G19B$' ?#g@ BK2PX@"SCQCQD@MWSDY@ ##T%#++'.5737>32#"&#"3ve.KFd AcI>3  +I8& aKW NbW]0\8ZA];K^@9$BKPX@+ [[CSCSD@.h [[SCSDY@=<[YSQEC32.5467#".54>32!2>54&#"4&'.#"32>0"(")1)BzmWe7RY$G# &^<:eL,5fbnQ~ ~6R9YN6R8W 6_*RxN&yoBmM+2PD<32#>54&#"OSOes|LL=B-_ZNATvy+{%RP1ZN_GK PX@SCC D@SCC DY@  +##".54>32zz#,,!",,# >-##-.##/g(Y BK PX@SCCSD@SCCSDY@%#U%+#"&'7>323267#".54>32-LiC#2 GE #-+!"+,#=iN- ` IQ@>-##-.##/N0@-B\CC D%(%!+3267>;#"&'.+#jOy 0 "; Ws  X@C D+33X?G0Z@  BK"PX@SC D@CSC DY@00&%$$! +332>32>32#654&#"#>54&#"GzY<KcgbLhpoLL2;+VPEAM/;0YOD?<~2{1(KG+S{P0GD0[RGP@ BK"PX@SC D@CSC DY@ &$!+332>32#>54&#"GyY<Qmq}LL=A0c\O:<Ć*{%RO4_S7#NK PX@SCSD@SCSDY@## +%2>54&#"".54>32IxT.nhJwT.mYSd8PnSd8P}P_O_9ldb9lcc+@BK PX@SCSCDK"PX@SCSCD@!CSCSCDYY@#!++(&!+32>32#"&'"32>54&Y<&Zcl8"?YmFK|*60c\O &k74\L<)VM5#".54>322>7.#"p ;#PZb432&#"GzY AY** /,a38 * 99@69BhfSCSD/#%/#"+#".#"#"&'7>3232>54.54>32 !/D0-J6>^m^>7gZa/, 0I81O7>^l^>3`V[2S ,;!/8)&:ZHFa:E6D #2C&3<(#7XI@w\7=4_>0b+BK2PX@#jhQCSD@!jh\SDY@ %#(+&+74>7#"&54>?>;!!32>32#"&?q K^, =/)( %0}?ap$:/ 9)2 31 U+1j`#LBK"PX@CT D@C CTDY@ ##*!&+32>73#"&54>57#"&5467bL=B.a[N?zX"Qjq}L|$RP2\P "("Q*K@BC D, +32>7>;#K :t%J$$I& Q. @'BC D*!,< +32>7>;2>7>;#"'.'+Q] Jq W{ t#A A#p#B! C# "! R"@BC D(")!+32>7>; #"&'+h    !   /+Q@ BCD,"!++32>7>;<)  @)*+Y@QCQ D+!!7>7!7!P 6  K#&J #ߌ1YE7@4&:B[[OSG=;303++4𑯎.54>;+";2#".54>85 JI-YV1  'B/"3;5@#C= 2EfC" & 4Bhw|575ai7MEoQ;?<MgA![?;2>5<&454>7.54>54&+"&54>573285 JI-YV1  'B/"3;5@#C= 2EfC" & 4Bhw|575ai7M EoQ32AI%Ef@4f_V$AI%EeA4f_VeUFCpP, '!TGCpP-!'! !&@#SCQD +>73 4>32#".C  hB."--""--"-UW\45\VU-."".-""-&/8@%BK PX@.jhfkSCSD@.jhfkSCSDY@ ##'#+.54>?>;#".'>32+R`4Mф"@-R}04 +=*@[?* '!S`i6!@tjZ]0 Dq`~מ\ ?1< "<#6&Dv>?@<+Bh[SCS D&&%#%&" +#!>3!#!7>7#7>;>32#"&'.#"!zY 60<  ;#9+$q! PmT{X9K#2H4AkQ3 Kj*I p /C..F ^zF&B[5, 0$+OpEF+`#7?@< !B @ ?WSD42*((+467'7>327'#"&''7.732>54.#"![,h:9f+Y"![,h99e,Z!#>Q//S=$$=S//Q>#9e,Z"![,g:9f+\!![,g:.Q=$$=Q./R>##>R~"8@5 B Z Y C D"! ,! +!32>7>;!!!!#!7!7!6ʐ  _ "6 V '' V p'!:; =cicAci5@YQD+3#3#;FVA@>FTL;!BhfWSDDB+)&$#!+#".#"#"&'7>3232>54.5467.54>32>54.'R!/B0/K6DfvfDY_%-6f^a00 !0I:2O7)BUYUB)ag%.3aW[/:Zn3:26Ug1E9.>".A88JdH[)!U9J`7D6B "3E))<0(*0?R8Y'"X>AvZ5>6/B82V51D70#P^'@S D((($+#".54>32#".54>32? )(() g))))((**((**]+Ga@ BK PX@5h f[[ SCSD@5h f[[ SCSDY@\ZPNB@42(&++ +2#".54>32#".#"32>%4>32#".732>54.#"; <9tbs?Dzbm9. 2M:GpP**Kg>?V9!.4`ee_44_ed`4e,QsXXsR-cXsQ,@BIDzdeyCC8A -TxKMyR+e`44`ed`44`eYtS--StYe.Sv?-9L@I!Bh[ WSD/.32.9/9%# -- +"&/#"&54>?6454&#"#"&/>32'26?.04AR%Vj(0"0$6xD,D//.G$ B\9*H 1  ED(K;&& .6 (2.4G(P&#m*"%%(+774 o ;]4 o ;      >=K PX@_MQE@kMQEY+!#![4$9^ a<@MQE+!!s8^3IV>BK PX@/h  [ [SCSD@/h  [ [SCSDY@44VTLJ4I4H)!*,,& +4>32#".732>54.#"#!2#"'.#'32>54.+^4`ee`44`ee`4e,RrXXsR-c焄b kj ! Ps8M/+F4e`44`ed`44`eYtS--StYee|}z^ . r(:&%8$pA@MQE+!!~Aq''@WSD((($+4>32#".732>54.#"3XvDEwX22XwEDvX3}6I**I66I**I6hCvW22WvCBuW33WuA*I66I**J77J3PK <@9jhZMQE  +!!#!7!!!/e--j/Dr{$d-9@6+ Bh[SD(&#! --+26;2!7>?>54&#"#"&/>`m0?"2* 6(6**A!CddS,HA<  *  89:-0+2 ji|d:S@P6Bhh[[SD31.,('&%:: +2#".'763232>54>54&#"#"&/>.K5980Nd48Q7" : +!"5%FV [S5,2=@5HWd->$-E7<]?!1G/!%011Y=>,-.+ 4P4 @kD #++7>3f" %2@/BCT CD%%'%!&+32673#"&=#"&'#"&5<7\SVQF=]|gFPA^#U %Y  RYJB lHC/+$H k7*@'hiS D+##!#".54>3ܵ붝j]i9Hq77]2Z~MZtC@OSG($+4>32#".)67((76)Q8((86))6w KPX@  B@  BYK PX@^TDKPX@jTD@jjTDYY@ +232654&'73#"&'76E(+GB:k JC!;Q0&B (# R?.$9'5z^N BK2PX@jjQD@jjMRFY$+37#"&/733!6 y   hNy u,\ 6]<!)@&WSD!! +2#".54>2654&#":]A"0UxH;^A#0Wy ZYA?2E+@%Ea;37#"&/733!>73n Ujw/F1!Gu6 y  hNy uI  >] [,\ 6],\ 7Hb@_B;5Bhh   Z [  CT D HGFEDC?=9820,* 7 7#" +%+>;26;2!7>?>54&#"#"&/>%37#"&/733!/F1!G`m3C$2* 6(6*/=  +6 y   hNy u5 [IdS-LC>!8*  89:-04) ji<,\ 6]zTZ~@{P " / X B  h h  h [  [\ S C DZYMKGEA@?>8631+)TT##!#+3+#7!"&/3+>;%2#".'763232>54>54&#"#"&/>>73 n Ujw/F1!Gu.K5980Nd48Q7" : 46"5%FV [S5,2@ 15HW I  >] [->$-E7<]?!1G/,2%011Y=>,-0% 4P4c,u';5@2BhfSCSD(&#,$+#".54>?332>324>32#".u!LWb8DoQ,/IWN: $u 1HSF/-;!7S<'  !-."".-!4''HgAQsS<56$-B:8CV;)?+$."".-""-&$ O&$ _&$ O&$O&$ O-&$P9@6AYYQ CS D# +!!!!!!!+!L*: &$@dJKPX@9= HB@9= HBYK PX@0hfSCSC SDKPX@0hfSCSC SD@7hf hSCSCSDYY@FD<;64/-%# JJ +232654&'7.546$32#".#"32>32#"&'76(+GB0r~BtL|fS$@(EmWtʔU:gUBfN7) AWߒJC!;Q0&B (# v dڀ6{2F+N (/(]o{B ' Q^o:?.$9'5aA&( $aA&( $aA&( $aA&( $V &, &, g&, &, E!,@)YS CS D!%(!+3!2#!#%4.#!!!!2>SPԕOpQ{7f]>\ ?2xŎN Z㈷vlyAn[aE&1d&2 d&2 d&2 d&2d&2 l9W  (+  ' 7 9|8fnPg0]d]e[]Z0%1=g@5*)# BK PX@kCSCSD@jkSCSDY**'(%&+#"&'+.546$327>;.#"%4&'32>4_kaCm=JMRrhEY `EJ+)2OvƎP$"<0wHxƎO2zڹh82/ T錷3|;6p Ta<.1_*X;&'^$&8 $&8 $&8 $&8 y&< < ++,@)\[ C D"( +32+#3 32>54&#rn6J΅!3JUX.6cUqLa4]Lt3&P}@ JGBAK,PX@(hSCSCQD@%hWSCSDY@LKFD=;%# PP+2#"&'7>3232>54.54>54.#"+'&573>Y~Q&/FQF/+@K@+>iOY10 "-@0*G3.DQD.1JWJ1-I4>mU: l.KFn(^6Se/D`H638&#/)+=XAV_3E6B "6I*0?.(4H8>XE:@P8;0CtUKW!M\K0&DCi0&Dv+0&D"0&D"0&Dj"0&D6GUbG@ E?"BK PX@5hh  [ S C SDKPX@5hh  [ S C SDK,PX@?hh  [ S CSC SD@Jhh  [ S CS CSC SDYYY@&WV\[VbWbQOIHCA<:75/.(&  GG+232>32#"&'#"&54>7>54#"#"&/>32>32>7">54&]W8wxGc>(!)!7QP`UT^%32#".#"32>32#"&'76(+GB2JqL'Mrd38 +A3E{\58Q6-F6)!,/TTW1JC!;Q0&B (# y CkT{hGDC Kf>eG'!63H-<?.$9'5;q&HC;&Hv;q&H;&Hj=&C_u&v"^&/w&j<1E6@37-B10@[SD32=;2E3E+)!+.54?.'&54?7#".54>32.'2>7.#")`7%XFqQ^FȂRe8E}ia0LL!AoX> &32#"&4>32#"&B&2'&21;X&2'&20<2&(1$>f2&(1$>%)4@32#"BK PX@!CSCSCDKPX@!CSCSCDKPX@!kCSCSD@!jkSCSDYYY@+**4+4&$+"'+7.54>327>;&#"2>54&'|Z$:C(+Pn}[" Z'+P8NJzY1I{Y1 F7=15Xb@.5WcYBZ-LsMg,K ,`&XC++`&Xv++`&X++`&Xj++Q&\v++%,p@ BK PX@!CSCSCD@!CSCSCDY@$",,(%+3>32#"&'#"32>54&%ݰY&X`h6"?YmFK{+.'0b\O!&k74\L<)V4=eF'R_6;6&!.' Y0LRVB N %_-&(   @F:?n)^g !*3 ' QB&&C04F(KPX@&;BK"PX@&;B@&;BYYK PX@#SC SCSDKPX@#SC SCSDK"PX@*hSC SCSD@.hSC C SCSDYYY@65?<5F6F1/('$"44 +2#"&54>7.57#".54>32#32>2>7.#"> Y0LR*:"$S]f7G Y0LRVB/<=ui-&(  @F:?n) !*3 ' ;qAPKPX@G2B@G2BYK PX@*h SCSCSDKPX@*h SCSCSD@1hh SCSCSDYY@CBBPCP><0.)' AA +2#"&5467.54>3232>3232>">54.I Y0LRI9U_2!?[uQMpH#6uv0K;-& ,MT+$(  ?jR:d #8 @F::f(324.#"32>;=qZuFhKkS h/ZSmI0[SmHr~\ㇹ6~&Ge?j|Dck|Cb.4FU@ L2 "BK PX@$h S C SD@$h S C SDY@ HG65GUHU><5F6F0.&$ 44 +232>32#"&'#".54>32>2>54&#"">54.AhJ'8\~ym0K;-&,2afp@i'E΁QzQ)Ukk#?IQ}U+]aN|X/.JH;fP8 h&'="?X5)LC;0& #74L1tsny;eHXe[ZfvNqsLy/VB( .YQ3:A!*! &6 #&Vv++ &6 ,&V~++y&< < ++&= 8Y&]v++&=8Y&]++&=8Y&]++i'6@3 BYSCSD''#"+#763>7'.546767376$3#"!2 :.UH8*0 /UI9+G!˹[7:^E  ſ_;^E}Q@Bk D, +#"&/.'+3r d w q@Bk D( +32?>;#qx d  spAq @W D +".5467332>73r>V6y4B'6#z&Eg!:M- 3?)9!6aI+@SD($+#".54>32#.-""-.#:-""-/##/kJ=KPX@WSD@[OSGY$&($+4>32#".732654&#" 7H()I8 8I)(H7 d6/-77-/6#*D22D*)D00D),88,-88/t YKPX@ B@@ B@YKPX@ SD@jSDY@ +2#"&54>732>R Y0LR.@%W-&(  @F:"@:2 !*3 ' hQK*PX@WS D@O[SGY@ +273#".#"#>32Ai!2B% 5-) (j"3A%!4-()X/M7#-,.N8#) #@ SD   #++7>3!+7>3H"S   !YBK(PX@SCS D@SC CSDY@! 6##++#!#"&'7>3267#7>3"|lkOz=<;N D#u}w H ?C?  @MQE+!!}o@MQE+!!7}(+.5467j^/ ! %J%dL  09@"6 (+'&5467>54&'&547pj^0 ! %J%dL  08@#6 (+7'&5467>54&'&547j^0 ! %J%dL  08@#6 1(+.5467.5467j^/ ! j^/ ! %J%dL  09@"6 *%J%dL  09@"6 1(+'&5467>54&'&547%'&5467>54&'&547yj^0 ! j^0 ! %J%dL  08@#6 *%J%dL  08@#6 1(+7'&5467>54&'&547%'&5467>54&'&547j^0 ! j^0 ! %J%dL  08@#6 *%J%dL  08@#6 %,@)  BCSCD$&$"+>3632>32! #"&'!,*?G#)33#P$KIF &!6H0+u6/, ) D B9E@B  )!("B[C SCD98'%#&$" +>3632>32!!#.'#"&'#"&5<>7!!,*?G#)33#P$KIF &"Pj.*?G!0+O$KIG&!kP/, '(v://  (,KPX@ SD@OSGY($+4>32#".:eLMe;;eMLe:SMe;;eMMd;;d-,';@SD((((($+74>32#".%4>32#".%4>32#".-"--""--""--""--"!..""..!n."".-""-."".-""-."".-""-Z'1EYmKPX@+[   [SC  S  DK PX@/[   [SC C  S D@3[   [ CSC C  S DYY@~|trjh`^VT((%#&((($+#".54>324.#"32>>;+#".54>324.#"32>%#".54>324.#"32>;`{A8^C%6]}F8^C&$1(G4$1'G5w | ~:`|A8]C%6]}F8]D%$1(G5$1'G6):`{A8^C%6]}F8]D%$1(F5#1'F6xcj7)MoFck8)NpH2H."JsQ1E-!GqU  ci7)MnFcl8)NpH2G."JrQ1F-!HrRci7)MnFcl8)NpH2G."JrQ1F-!Hr(+74 o ;   w(+'&54767&'&54?5  p!;{   c @ C D#"+'+>;?/F1!G5 [*B[@X 4 Bh  h [   [SC S  DBA?>=<861/"##%%$+3>32#".#"!#!!#!32>32#".'#7367#T!wp;C  &6J3MoT0dRoI. ASގqv>  ̎LcWB  4f`7#H&6-6-DeqRҀcJGI6%B@?BhS  CS  D%%!4( +>7>;#7+"'#32'###7  fGk. }.iGg 54.#"!"&546767!7.54>32!5Ti<5aReH*Lj@4/LxR,0X|`zȎNAwf~ (JxpZ_0BzMyY:O%TvTatQ+Lprěla A3HB@?"Bh[SCSD54?=4H5H#*++$+>32#".5467>32>7>54&#"#"&'2>7.#"'JMT0ItQ,n݉HwT._g^" e\'C7) :qdU .I5K{\: ]9*8lc?!/X~P#sʔVRQ"=9 7or-S@'>mWgp @ B CR D+)3!.'ԩ   9 !9 $@!Q CD +##!##7Ȳɱȼ]]$@!BQ CQD+!!!!7>7 &5<7RA ! ;4;A ^@MQE+!![Ll"@Bj[ D,'!+!##"&5<>7!2>7>;p"Ne [n  [ A 7Q=';OL@IK-B[  O  SG=<)(GE32>32%2>7.#"!2>54.#"{3P?1DNX35[C'7\xB3O@2DMX35\D'7]y!<86$,4!&A1$1S%B1$1!;86%+4!8K))K8!(KhARi=!9K))K9!(KiARi<5E''E4!32#"#"&'7>32>7)#A*\nOg}F D 6Q=,CWnuf_- L :^B7^@[0!/"B[[ O[ SG42+)&$77  +2>7#".#"'>322>7#".#"'>32@80% (u=4c_\-90% )wB4d^\81% 'v=4c_\-81% )wB5c_[W  l0."(" i31!)!  m/-!(!  h31!)!}kK PX@)^_ ZMQE@'jk ZMQEY@  +!733!!!#7!7!7!}w5}PwSʃZP @ @MQE+!!3-2/*>yz  z{ iP@ @MQE+%!7!7>7%>7.'%.54657n>2/aPz  z"@ BMQE+3 #>7 &'|y|  54&&EF,#& ~-KPX@ kD@ jaY@ +3v 0>'s@  BK2PX@(SCQC CQD@MWSC DY@''W%#+#!+'&5737>32#"&#"yk}f.KFc( Izk''#  SzU1 `KX #O8]n=Z $HnK5>!@ BK PX@(SCQC CQDK&PX@(SCQC CQDK2PX@,CSCQC CQD@$MWCSC DYYY@!!#!%# ++'&5737>32;#.#"3wg.KFb( BnaG5w-_+uaKX !Q7TpA Z$ 7G25K0PX@ QD@MQEY@ +#2~mQRU   @ja  +2#"&/  '@OSG((($+#".54>32#".54>32P%##%X$$$$$$%%$$%%(@MQE+!!4f  @ja #++7>3  f  @Bja& +#"&/+73ǃ r   kk  @Bja !+#'327>3ƒ r  kk(@%jOSG +"&547332673syoNOp,Ie^^ c><4T< *@OSG($+#".54>32"-,!!,-",!!,,"",V-!@[OSG$&($+4>32#".732654&#"4D&'E44E'&D4Y6/-77-/6{'B//B'&@..@&+99+-881@.O[SG +2673#".#"#>32)^.>% 82.'a.>%!82-|*%*G5 -%*H5  b +@(OSG   #++7>3!+7>3(S'])  } @kD  +2+ +$ <] 9^I D{_< ʓ^pӡ - VO'-{6GZ9(z(s2a-O/]-DhR-.++}Madia+aaEdpa61raaoadhrdr ?{?|Zy|(!l(8M0Ob<5;]?$O_gNXGG7 0G _`KQQZ(1X(9{~X;8^=]xka=^8p38;k#8kwd+a+a+a+a6V66g6Eoadddddl0????yhI3000000b<;;;;=_"/<G77777s````Q%Q0db<+a;_YLoaGd.    y|Z|Z|Z8Q8q8p8888/8h8x,,B-OZVVwA*/]+A YxL={+Z+i>G>8G8U8888f888*8888gP`  UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U U    U $U 96 :0 <- ?6 D F G H R T m o y } U U U U U U U - U - U # & * 2 4 D F G H R T k p U    U $U 96 :0 <- ?6 D F G H R T m o y } U U U U U U U - U - U  ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;;   ^^$7A9;<@=?lr|@@^^^  ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;;6  6 6AA":#$&*-i24DFGHPQRSTUVXYZ\]kl6mopr6tPuPwy{P|6}66A66AA## # # # ##$#7#9#;#<#=#?#@#`#l#r#|##################$J$ J$ J$$#$&$*$->$2$4$7|$8$9$:$<u><w<yJ<{><|7<}J<r<r<r<r<r<r<r<<<<<<<<A<A<A<A<A<A<A<A<A<A<A<A<A<<A<A<A<A<A<A<<<<<r<A<<A<A<<<A<A<A<<<<J<J<7<7<'<7<7<'<J<'<J<J<r=="#=#=&=*=2=4=k=m=o=p=y=}==============>#>&>*>2>4>D>F>G>H>R>T>k>p>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>?J? J? J??#?&?*?->?2?4?7|?8?9?:?247|89:247|89:247|89:247|89:247|89:247|89:u>wyJ{>|7}JrrrrrrrAAAAAAAAAAAAAAAAAAArAAAAAAJJ77'77'J'JJr $79;<=?@`lr| @[`lr| @[`lr| @[`lr| @[`lr| @[`lr| Y\lrtu{| @[`lr| @[`lr| @[`lr| @[`lr| @[`lr| @[`lr| rr$DFGHRTrrr @[`lr| rr$DFGHRTrrrJ J J#&*->247|89:u>wyJ{>|7}JrrrrrrrAAAAAAAAAAAAAAAAAAArAAAAAAJJ77'77'J'JJr"##&*24kmopy}"##&*24kmopy}"##&*24kmopy} ^^$7A9;<@=?lr|@@^^^ ^^$7A9;<@=?lr|@@^^^ UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;; UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-U ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;; ^^$7A9;<@=?lr|@@^^^ ;#&*24759,:|<;?,YrZ\|klm;o;pry;|};;rr;;;;;; ^^$7A9;<@=?lr|@@^^^ ^^$7A9;<@=?lr|@@^^^ UU$U96:0<-?6DFGHRTmoy}UUUUUUU-U-UJ J J#&*->247|89:|LrF(HxXd`(t(.lR@f|@@ !!l!"&"l#<##$,$F%%%b%&&&&'2'^'((Z()")**++ ++$+0+<+,n,z,,,,,,,--*-6-B-N-Z-f-. .,.8.D.P.b./R/^/j/v///0111111112 22222223L444*4<4N4`4456|667"788P8~889~:8:D:T:`:p:::::::;8;h;;;;>H>>?4?@@:@AAABBCCxDD0D\DDDEEFRFFG0GpGHHHIIJIdIIIJJ:JzJJKb"/n n) ( 0+ C R . 2F x: T h  p R|  P  `4 0   0  d  . 4Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.LatoItalictyPolandLukaszDziedzic: Lato Italic: 2013Lato ItalicVersion 1.105; Western+Polish opensourceLato-ItalicLato is a trademark of tyPoland Lukasz Dziedzic.tyPoland Lukasz DziedzicLukasz DziedzicLato is a sanserif typeface family designed in the Summer 2010 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in 2010, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness.http://www.typoland.com/http://www.typoland.com/designers/Lukasz_Dziedzic/Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic (http://www.typoland.com/) with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1 (http://scripts.sil.org/OFL).http://scripts.sil.org/OFLCopyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.LatoItalictyPolandLukaszDziedzic: Lato Italic: 2013Lato-ItalicVersion 1.105; Western+Polish opensourceLato is a trademark of tyPoland Lukasz Dziedzic.tyPoland Lukasz DziedzicLukasz DziedzicLato is a sanserif typeface family designed in the Summer 2010 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in 2010, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness.http://www.typoland.com/http://www.typoland.com/designers/Lukasz_Dziedzic/Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic (http://www.typoland.com/) with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1 (http://scripts.sil.org/OFL).http://scripts.sil.org/OFLrt  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#NULLuni00A0uni00ADmacronperiodcenteredAogonekaogonekEogonekeogonekNacutenacuteSacutesacuteZacutezacute Zdotaccent zdotaccentuni02C9EuroDeltauni2669undercommaaccent grave.case dieresis.case macron.case acute.casecircumflex.case caron.case breve.casedotaccent.case ring.case tilde.casehungarumlaut.case caron.saltVV, `f-, d P&ZE[X!#!X PPX!@Y 8PX!8YY Ead(PX! E 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #B *! C +0%QX`PaRYX#Y! @SX+!@Y#PXeY-,C+C`B-,#B# #Bab`*-, E EcEb`D`-, E +#%` E#a d PX!0PX @YY#PXeY%#aDD`-,EaD- ,` CJPX #BY CJRX #BY- , b c#a C` ` #B#- ,KTXDY$ e#x- ,KQXKSXDY!Y$e#x- , CUX CaB +YC%B %B %B# %PXC`%B #a *!#a #a *!C`%B%a *!Y CG CG`b EcEb`#DC>C`B-,ETX #B `a  BB` +m+"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-,+ETX #B `a  BB` +m+"Y-,+-,+-,+-,+-,+-,+- ,+-!,+-",+-#, +-$, <`-%, ` ` C#`C%a`$*!-&,%+%*-', G EcEb`#a8# UX G EcEb`#a8!Y-(,ETX'*0"Y-),+ETX'*0"Y-*, 5`-+,EcEb+EcEb+D>#8**-,, < G EcEb`Ca8--,.<-., < G EcEb`CaCc8-/,% . G#B%IG#G#a Xb!Y#B.*-0,%%G#G#aE+e.# <8-1,%% .G#G#a #BE+ `PX @QX  &YBB# C #G#G#a#F`Cb` + a C`d#CadPXCaC`Y%ba# &#Fa8#CF%CG#G#a` Cb`# +#C`+%a%b&a %`d#%`dPX!#!Y# &#Fa8Y-2, & .G#G#a#<8-3, #B F#G+#a8-4,%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%aEc# Xb!YcEb`#.# <8#!Y-5, C .G#G#a ` `fb# <8-6,# .F%FRX ,1+!# <#B#8&+C.&+-?, G#B.,*-@, G#B.,*-A,-*-B,/*-C,E# . F#a8&+-D,#BC+-E,<+-F,<+-G,<+-H,<+-I,=+-J,=+-K,=+-L,=+-M,9+-N,9+-O,9+-P,9+-Q,;+-R,;+-S,;+-T,;+-U,>+-V,>+-W,>+-X,>+-Y,:+-Z,:+-[,:+-\,:+-],2+.&+-^,2+6+-_,2+7+-`,2+8+-a,3+.&+-b,3+6+-c,3+7+-d,3+8+-e,4+.&+-f,4+6+-g,4+7+-h,4+8+-i,5+.&+-j,5+6+-k,5+7+-l,5+8+-m,+e$Px0-KKRXYc #D#pE (`f UX%aEc#b#D * **Y( ERD *D$QX@XD&QXXDYYYYDPK!^b8generator/template/darkfish/fonts/SourceCodePro-Bold.ttfnu[pBASEe]0FDSIGGDEFxGPOS#f8dbGSUB]JOS/2x`cmapspB3fglyfc[MOvheadʹ6hhea3y4$hmtxsp BlocanyA BmaxpT^X names@post+$9  7 _< s0:($X00( *bXXKX^2)   8ADBO ` X# J6F\i,@J;Dk:B&K&F2@8=HC/7R4HO*L2#H/H/t51>%F J66666FFFF\\\\\\\\^\\\\F\\\\,,,,,,,,,@@@@JJJJJJJJJJJJ;DDD[kkk*kk:::BBBBBBBB&&&&&&&&&&&&&&&&&&&&&&&&FFFFFFF22222222@@@@@@@@@@@@@@@@@@@@@@@@888888I2AJ&.=============='========HCCCCC"////7777777777777777744444444HH HOOOOOOOOOOOO*LLLL2222222###HHHHHHHH///////////////////////// tRttaa/55555555=R1111111>>>>>>>>>>>>>>>>>>>>>>>FFFFFF/HH*ABHHH4C//6/n7F0/*1/@<HHHOO2)2)y#HJ/444ttJJ5++21'>!FF42E29C/B////////////////////////////////QQQQQQQQQQQQQQOQOQQQQQQQQQQQ Jl\8@&JD:BB&@K?J *H5FVA7=I"@;3 H/2>)IH9*FA==3>>=>I0Jt)hjijsnoh} JJl \.@@E:@&@K6@-"J\\l72JJ;E@?&l2.E@6,>J \2@&&=<Tt70IIM%H/HHC2%H@##&Q5"77tC5OO*$MIK /%x/0MHC %@H2=77I////CQQQ8O3*#.<>=58O8O3*#.<>=58O8O3*#.<>=58ObgR3EE*;FFFPPvzZzZ|Y<<>c~hjiJJ@YYG0w><@\hhhhheFT|||@0t&|>$@C-`.OC[C5OY##4  5FFTFFFtbFFFVF44FFIFp@<}! B,;J ]>Gf J<9'H55AADDAA00 ,75.J#Z}uu}nm.}unfzmtwxuB9"munJknf0cho/uzsijj!!KK^^^^^^^, ,,5 >A$,$  Rklmnopqrstuv  !"#$%&'()*+,-./012345:=R^ *)+-KJLNipoqsrVSMT&(uWo69hUl8_7a]~U /9@Z`z~7C\ghnv{~  *,14=E_auz~/_cuCIMPRX[!+;IScgo    " & 0 3 5 : ? D I q y  !!!! !"!&!.!^!!!!""""""""")"+"7"H"a"e###!%%%%%%%%%%&&&<&@&B&`&c&f&k''R'd'..% 0:A[a{7CP^hjox}#,.49@_atz~0brCGMORV[  $2>RXfl~    & / 2 5 9 < D G p t } !!!! !"!&!.!P!!!!""""""""")"+"7"H"`"d###%%%%%%%%%%&&&:&@&B&`&c&e&j''R'd'.."=oY xpo%$#$    ;:.-iodcj$~|yzzTiplG%s޺ޚޙrmcݹjqվջ%y%l  "",028>HNPZ\^bfprxzz||xz RkloVSQT&(mno6789:=MR]^_a~ )*+-JKLNiopqrs;< @ S T!V#U"W$[(b.c/d1e0`,p<q=r>s?xC}IMOTQUVWZ[]\bafjhntuWw? PvOt@wo;g> N2:?AH4;@I   "-./02467C#JEvwxy|~z}JKLMNOPQRS T U V W XYZ[\]^_`abcd*,-358<=QX%Y&Z'n:uAzEyD{G|HXY^_`cdeklmFABCDEFGHIJKLf2g3h4i5j6k7l8m9RSxyz{|}~l16gY]Uebckx}~pqrstuvwyz{| $ !!""##$$R%%k&&l''()**++,,--..//09m:;<<==>>??@@AZ[[\\]]^^__``az{{||}}~~oVSQT&(m6=MR]a~ )-JNio;< @ S T  !  V  #  U  "W$[(b.c/d1e0`,p<q=  r!!>""s##?$$x%%C&&}''I(())M**++O,,--T..//Q0011U22334455V6677W88Z99::[;;<<]==>>\??@@bAABBaCCDDfEEFFjGGHHhIInJJKKLLMMtNNOOPPQQuRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~\Ww? PvOt@wo;g> N77CCPPPQQRXY\^ghhjjknovx{}~02:?AH4;@I           " $#&-''2((4)*6,,8.1944=9=>@@AABBCCC#DDJEEE__FaaGtuzz~~vw{|~^oz}/0_bbccJrrssKttuuLMNOPQRS T U V W XYZ[\]^_`abcdCC)GG*HI,MM/OO3PP5RR7VV8WX<[[>+.BQ  X  %Y&Z'n:  u!!A$$z%%E&&y''D(({))G**|++H2233X4455Y6677^8899_::;;`>>??c@@AAdBBCCeDDEEkFFGGlHHIImRRSSXXYYZZ[[\\]]^^__``aabbccffggllmmnnoo~~FABCDEFGHIJKLf2g3h4i5j6k7l8m9RSxyz{|}~  p                       ! " " & & / / 0 0l 2 3 5 5 9 : < < = = > ? D Dh G G H H I I p p q q1 t y } ~  6   F X g Y Z \ ] U d ^ ` e b f!!!!!!k!!! ! !"!"!&!&!.!.!P!Px!Q!R}!S!Zp![!^y!!!!!!!!!!!!""""""""""""""""i""""""""")")"+"+"7"7"H"H"`"`"a"a"d"e####### #!%%s%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&:&;&<&<&@&@&B&B&`&`&c&c&e&e&f&f&j&k'''R'R'd'd''...".%**M'<Qp4pWJ}<_ju)X0K&1<G   & 1 < G R `    $ / : E M ~   * 5 @ K V d o z   $ / ; F i t     ) 4 ? J V a l z $/:EP[fq| Xcny*5@KYdoz  +EP[fq| "-]hs~ #.9DOZe;br}*5r}@KVa4?JU`kv  +7Bmx !9DP[ft "-hs~%0;FT_j +(q%0;FQ\gr ! , 7 B M X c n y ! !!!*!s!!!">"""#$#g##$$_$$$%%O%%%%&P&&''H'k''''( ((/(:(u((())7)w))**-*d***++E+d+++,(,^,,,- -6-S----.6.f../G/o///00O00000000001=1H1S1^1i1t111111112 2(232>2I2T2_2j2u2222222222233 33"3J3w333334 44 4.494V4b4444445 555%5V5^5f55555555556)616R66667 77E7k7s778=8i889(9R999::;:]::; ;=;p;;<<>>>$>c>>>??? ?)?8?F?N?]?e?m???????????????@@!@=@K@S@v@@@AASA[AAAAABBLBmBxBBBBBBBBCC*C\CdC{CCCCDD;DiDDDDE EECEKESE[EcEEEEFFF)FSFFFFG&GfGGGH HH7HhHHHHHHHHHHIIII%IjIIIIJ#J_JJJJKK)K1KCKKKSKdKlKKKKLL/LQLwLLLMMM'MdMoMMMMMMN"N*N5N@NKNaNNNNNO,OkOOOPP#PHPyPPPPPPPPPPPQ QQQ'QqQyQQQRKRRRSS,S^SSTTITTTTUURUvUUUUVVJV_VVVWW@WtWWXX_XXXXXXY,YMYnYYYYZZ>ZKZXZaZnZZZZZZZZZZ[[[[3[_[l[[[[[[[\\\;\G\S\f\s\\\\\]*]k]z]]]]]^^_^|^^^_P__``+`:`I`X`p`````aahaab0bbcc&c2c:cBcccccccccccccddd7dNdpddde,eDeeefff3fYflfffg gBgZgggh hhkَ7iю Ky5eӐ!5IlՒ .QӒ&Cdēԓ&6FUeuʔߔ1DWjӕ$7I^rÖ֖#;Tl̗2JbzϘ !6Kezљ-E^}͚6Mlۛ*DTeŜҜߜ%7DP]jwŝҝߝFߥ!1EVgu"Mpx#5 3!%3''#7'377##(()|__+u^l[Mbb p_;;s O 3'&&'#3#'#   ˰˜'(J<<1m44mtJ2"332#32654&##3254&##JDl?6:FHBqG[A6014BOv9=OF?+S KACT)+%$ZX+&6:"&&546632&&#"3267dQTSW>d!Q7$E[]I#;QQ LmlQ3 [pbdp Y`F4 332#'326654&&##F_NM[)3M++M3DppGw(\NNY%\ 3!!3#!\&|{|i 3!!3#i||,#"&&546632&&#"32675#53WSPPTB^Q2'@UNM# _!m LmmP3 [pbdp px0@ 33353##@tJ 353#5!#3JĘ|||l|;"&'73265#5!6u+U9C23.k 0<[H4C'{R@j@DR 3333#D֣K wck 33!k"|:333773#54>7##''#:@@|22H3/ZZtQXPPXQB333&&553#'#B884:tE6|:&2"&&546632'2654&#",MwBBwMNvBBvN3<<33<< NomMMmoNljekkejlK1 332##3254&##KGsEFtETKx=;K'\OLb/Rh3*&NG &%2654&#""&'&&5466323267,3<<33<<_XjBwMNvB`QC# 0llqekkeqlbLmMMm"n FH332#'#3254&##FErE@4}MHw<;H%XNH]`a0&2'*"&'732654&''.546632&&#"*B5U%Y//-6/T$@'=lF;r,K"D0%-MC3$xCGIE7#"3&"&&546632!3267>+< KN|IJvBMh5 L="=!1+h./]h=uRRt>?kD% 62YRI3#57546632&&#"3#Ճ.cM+L4]}m 9]6 l Ws4-<0<J"&&5475&&54675&&5466323##"&'3322654&#"2654&##"'@f;M!&;a8.$d7\:" T\bgHR,,++,;K,+>3#D9,=& )2B+33366326632#4#"#4#"#o 2+D5+5:s =+Q"/VJR-0R-H3336632#4&#"Hx  T7TN )-B .l^2./)"&&546632'2654&#",BsHHsBBsHHsB3333333 =uRSt==tSRu=wM@ALLA@MHH)336632#"'#2654#"Hx N(]j=b8D6U)9[/--2#sUx?6Q$FL./H!57##"&5466323732675&&#"}D#^s=a6*A s+)(<2P yQu>!3X$CGIEt$3336632&&#"tx %i;!)%.Y l=; {6C5'"&'732654&&'&&54632&&#"(C/?.e5)&41eXzjCm'B%T)"#4?MT"} -\ K:EV+X+:)C]1&"&&55#57733#3267O^)}y270!O 7bAms80 j > "&5332673#'#UL),x !Q l^21/!FG%.9 33366773ڻN    N%M''M%T 33366773366773#'&&'#UQ k  L  %H&&J#%H&&H% H+:Y%23'3366773#'&&'#%3    ,9   1P+,PR,+R>;"&'7326773366773&+1 גS   IU*F 35#5!!F O.sNs O~& O~& OC& OT& ON& O/& OP& O~& O +"&54773'&&'#3#'#2654&#",3?+;S"@j   ˰˜'(6-5R( / -6<<1m44mt OT& g %3'&&'#"&54667#'##33267   1D(('(˰*3 #;J<<1m44m2. 4% t9  J O&- Ov& O&T O&V O&X O&Z OC&&- O&\ O&^ O&` O&b OP&& -S3#!#3#3!5#T svvv-d]1]q|||S~&M[S/&M[ 4!*35#5732#'3254&##3#532654&##TKKDk>59FHBrGRFu8=Fjj95233:EE;*K OEDY*lf3-SPPTKB' E[pbdp px0LmmP 7Nm!@C& @N& @ & -& 3_@& 9U3#57533533###35#@====E^]]]KSJ~& J~& JC& JT& JN& J/& Jd& JT& J "&54667#53#5!#3#326731C#Ę*# ";2. 3% |||l|1 JJv& J & -JP&  ;C& DR& 0D R& -DDR& <[ ~& k & k & 0#k  & -#*  /& &-#kD & <#  35'737!k@2r1"&X@JdX~|k=&  :~&:d&: &-B~& B~& BT& BT& B&0Bd& B &-BD&<&2~&&2~&&2C&&2T&&2N&&2/&&2y&&2P& &2T&&2!-"&5467.54663232672654&#"B1C+Oh3BwMNvB`P(! #;33<<33<<2.)= ^XkOOj#5 JSipekkepi& 2&-&2v&&2&T&2&V&2&X&2&Z& 2C&&-&S?("&&5466326654&'7'2654&#",MwBBwM?4 m s'+BvN3<<33<< NomM '$# ,5r+WoNljekkejl&S~&&S~&&Sv&&ST&& S?&-&2&fD )77&&5466327#"'7&#"2654&'EBwMV=5PDBvNT?6Z(3NuABsL);9 PiVOe )PkjQ@UU@A,"&'7326654&#"#36632i0  0+7G+:\6X !YTq]&$1>#'AzJJ33"&'732653Jy"+  !Pt m')~6[7&A333"&5463233&i )) ((6i|)* ** *|.JW~&'h=/&=/&=&=&=&=&=& =&=n)4@"&54677"&&5467&&#"'6632#'#'26752654&#"@AC;M)*C2I(42$I*43u@hxx %[!:IQ &P8=++{J# 6!+=(D*SX "&`&nr8(rR" =&=.,7"&54667'##"&&5467&&#"'663232726751D( %[02I(42$I*43u@hx83!?!:IQ &21 1# :((D*SX "&`&nr4AIR"= &-=&=U)&S')&U=>2&W=F&Y= &&-=t&[=t&]=y&_=E&a= && -Q3@"3&&"&'#"&5467&&#"'66326632#327%3267&&55({1M%F%;Jos"/4)Q(&;@$4F#4$%'3I 7)-65.h("("P>NZ.` )) AmA" 32_ - ,Q/& Q& )&"'###57533#36632'2654#"RH? sBBI#]k=bY)8[/-- B6)FHGL1InRt=x@H|.HD)&< C#&2*C#/&*C#&*C#&*C#& *"z6!&"&5466323'53#'#72675&&#"3Te6V/#2o ? "2+" yQu>MC3&xCGIEb/ &-/D&</&2/R("&5466323'5#53533#'#52675&#"_s=b5*;BBx H+'**<2 uNp<M*LGGF3$x!?BC@7#/&  7#/&  7#&  7#&  7#&  7#&  7#&  7#2"3&"&5467#"&&546632!3267327>+< 3B# N|IJvBMh5 L="=!138 ?./]21#8=uRRt>?kD% 62Y".&B7#&  7 #& - 7#&  7#&  7M)& S #)& U 762& W 7#F& Y 7 #& & - 7#n& e 4-</&"4-<&"4-<&" 4-<&" 4-<&"14-<&"4-<&"4-<&"&#e<&#e<H &#-HD&#< &#2eH&#93#57533#36632#4&#"HBB Q8SN )-)FHGL+`-l^ 2.O/&U-O/&U-O&U-O&U-O&U-O&U-O&U-O&M -O&U-O &$--O&U -O!#5!Z}s*<&-LI&&0L I&&-LDI&&<LI 33773#'L˟JH{2 &'<2 6&'2 &'0C2  &'-C2  k&'&<-C2D &'2&(#>&( # >&(-H/&)H/&)H&)H&)H&)0H&) H &)-HD&)<&3336632#4&#"'667#"&54632x H1JE!'48 (47)8=W@-k]!1-"NE/3).7UKR}/)/&*/)/&*/)&*/)&*/)&*/)&*/) &*/)&*/)!-"&5467.54663232672654&#"@0B+Ru=wM@ALLA@M/Q/&/Q/&/Q&/Q&/ Q&-/)  (77&#"'7&&5466327#"&'72654'!33P9. HsBK=.9/ HsB%F33Q.7!W6St=&7/8 X6Ru=KR@!/)/& Q 872654&#""3&&"&&5466326632#3267#"&'%w2S12T3'=D"3E#5!#3H$K>kM@AMMA@M!.55.h=uRSt=*11*AmA" 41 _'//'t$/&-1R$&-0t$&-1t$&- 1a $&--a $&-&1-/D$&-<5/&. 5&. 5&. 5R&.g 5&.2 5&.05&. 5 &.-=;4"&'732654.54>54&#"#46632)@"1*./('2eLAS)./'N d  $3(,(+#<3>c91M+$2%"&9,-K,RI3#57546632&&#"Ճ.cM+L4]}m 9]6 l W1&6&/1&&/2K1&&/0D1 &&/-D1D&&/ /&0> /&0> &0> &0> &0> &0> &0 > &0> &0> &0>$&"&54667'##"&53326733271D( !Q5UL),:1!?210# J%.l^21/!F4A> 9&0O> r&0H> i&0Q> r&0K>  &0-> &0>n!"&5332673>54'7#'#UL),!)m 7*x !Q l^21/!F'&+/77D7G%.>n/&>n/&>n&>n&> n&- 9&1-T/&2T/&2T&2T&2>;/&4>;/&4>;&4>;&4>;&4 H&4->;&4>;&4F/&5F&5F&5 F&5F &5- FD&5< /&/7326544'&&#""&&546632&&''7&'77F13>9 6?rCqD>e:$C 0#(w*2@&H"(o@MLK :;lIHe6-IKD<Y)ED8b6%>U(:,0..uMsUx?Q$FLCCHE "&'73254&#"#336632q)  / )-x  T7TN!J mQ2.B .l^7\7*<"&'73265#5!.K +15'Z(di 36es.54&#"(hxx &Z02I(42$I*43uIQ % !: nr8'(C*TW "&a&#H) "&'##336632'2654#"Q"F sx N+>Y0=cZ):^,, " 63$>pLVy?xDHH' ,"&'##46632&&#"36632'2654#"S"G s+_N$:"+*G$\j=`Y(8Z-. !!6:`;l(.LoSt=xAI}4"&'732654&#"'66324j+<=%AQM8: D i>I}LK $%]M@AL[&=tSRu=C-+%"32654'67&&546632&#"6632#"'*8!"')r!!$PL=] @2@AW/b*DO.V>F;@ !1A5!Y7St=%X+PD%-.E=*F*//Vm"/"&&57##"&&5466323'5332672675&&#"7H#B#>]4=`5)9$),%83*E(? >uQQu>MS%"lCGIE/l -"&5466323'546632&#"#'#72675&&#"]p<`4';"K?  x H)-$72 yQu>M,H,l#%3$xCGIE6!"3&&"&'73267!&&546632X ::1i*0!="=M :mLBqEI}]/.hX26 &Dk?>uQRt>/!"&&546632373#'#72675&&#">_4=b8&C sx K+)(<2 >uQQu>!33$xCGIEn=7""&&5467!&&#"'6632'267##Mj5S G9"=!0+h1LwEHtH-: @mC% 51X>tRQu>p/1`o(2"&&'7&&#"'663273267#"&'744'326BW, +-1&S%DbKC  #">$4]  ( ) >h?y"]:6$8(F $:Jq@ H(6F"*"&&54675&&546632&&#"33#"3267=FpA>5.0>nF7j+5 H&91eCR75>E+I:.k #E326 ;2=],c]%0!/"+"&&546632'2654&##532654&#"n,9"&'732677##"&&5466323'46632&#"2675&&#" )g,1#I82A">\3>a4&8"L@  b(,%83a."?>oGLq>#(K0m%#3afEC>=C/<,"&'732677##"&&5466323732675&&#")k,1#M79H#>_4oGLq>?3 dpGC>=C@ "&&54>32&&#"3275#53QI|L.Oc5DX"B/(#@'H9$\ j 8rW?bC#%X B5ELSb&-9%"&54673366773'2654&'#/IW#R    R$WJPB&A0 4##4 h1B&BP\) +9#/"&5467&&#"'66326632&#"'2654&',Zn7.**>)R%%S(>*(/6nZ""#" ^X,\*k %**% k*\,X^w$99$Hd#B=&,85+1N lIIf5/"[82,1Gy33!y s5#'##"'#"&53327332675o  3+D 6+5:s =+Q"/VJ\-0O-OH5 57##"'#"&53327332673 -)D 6*4;s a,Q"/VJ\-0O-OX#E>+"&'732654#"#4#"#3366326632%  s o 2+D6*4;Am Z-0R->+Q"/VJ0O0E "&'73265336632#4&#">$x  O4TL #*Hl!%B .l^7)4W4HEt "&&54&#"#336632327&@I #*x  P4SL %4W47)B .l^%!lJ333&&553#'&&'#J    <.\%<.[&/)"&&546632"3&27#,BtGGtBCsGGsCYY_ ;tUVs;;sVUt;``jjQ%"&&5466323#3#3#'27&&#"8f@@f8,"힀/ !3& 8sXXs:tMcXtsBM7?G?#5.54667534&'668b;;b8|9a;;a9.&&.$.&&.=oOOo==oOOo=CJ"IDDIJ4#'##"&'73267x %i;!)%.Zl=; {6C4"&'732673#'#!)%.Zx %i |6CCl<<4E2"&&55##"&'73266733267=FY0+!$40  ./O/m56 |0(("k tE$"&&5336632&&#"3267IN^)x %i;!)%.Y 170!P7bAl=; {6C9/ k t$346632.#"t8v]5T!!A-GqC {D;J6332#'#32654##J9]79)mGV('OVG>:H$<J673254&#3##33VO'(^)97]9G<$H:=H5E5"'3267#"&55732654&&'&&54632&&#"(99  )XI?.e5)&41eXzjCm'B%T)"#4?MT"}  ij^3\ K:EV+X+:)C]+<1"&'7326546632&&#"1A*&&%XL.=%"+""R f +,9^8 i +, 9^8+<1%"&'732655#57546632&&#"3#1A*&&%XL.=%"+""R f +,E9^8 i +,K9^82h'23#5#5354&#"'66O^)}y27/!P7bAms80 j 1E&"&&5#57733#3267O^)}y260!Q7bA^ms9/ k X "&55#57533533##'#'32675#PIRRVVx K9' k]NEKE%,5)b'1#"&&54675#5332654&'53#,Op:/W!2451!W.:o >b5>)"&5332654&#"'632*l2-/3 -Kd9q yv @:\P;8mcl^N9 #'&&'##~N    N&L''L&T #'&&'##'&&'##33677Q k  L  %I%%K#%I%%I% H+:Y93>32&#"#'&&'#;S=%(/ גS    I >V,p(-#K'%K%!9353366773Û64–Zk#?&&?#kFEz"&&55!5#5!!327-@I %3P+ O.sNt%!lFM %%"2232654'67#5#5!6632##  J *G+1:U\ $5.O.sOEL76.1G'm#!(6(4)<4"&'73265#327#"&55#57733546632&&#"r)  4$YMDKz"PD# !Kl')~*% k jVm3X6l')6Z723>54&#"'6632BM A8*FI$pMDsE+O59(:5 /3)]'9/]G6QF'E#3.546632&&#"5O,FsDMo%IG)7B MB'FQ6G]/9'])3/ 5:(235#5736654&#"'66323#͗L]PM=4,JI&tOBoCG0E0\*/3)\(8.]G7`%K9#35#573&&546632&&#"3#L80GCoBPt%IJ,4=MPE%`7G].8(\)3/*\0KCH#575#5733#3#㠠_4=b8&C sx K+)(<2<8=++{J# 6!+=>uQQu>!33$xCGIE/&/ &-/&/I)&S)&U/22&W/F&Y/ &&-/t&[/t&]/y&_/E&a/ && -/('4"&54667'##"&&54663237332672675&&#"-?! K$>_4=b8&C s3' ;+)(<2211$ 6$>uQQu>!34 AOCGIE/</</&6 /<&6 /<&6 /<&6 /<&61 /<&6 /<&6 /<&6 Q4&@ Q4 353#5!3Q/s ssQ4/&@Q4/&@Q4&@Q4&@Q4&@Q4&@Q4&@Q4&N Q4&@Q 4&?-Q4&@ Q4&P O"&5467##5!3267_1D6 *Z2*   ?21.?}s3AQ4"&5467#53#5!3#3267N0D4۱/2(  @21.?s ss3AO. !5#575#5!3#ZEvsKQ43535#575#5!3#3Q/seEZsKes #3267&#"&&'#"&54632#5!" $),  Q5T_WO,*Z6-/!V>>O QFC35&&55336553etQ|Qtetmn=nmt9'3535.5466323#5>54&#"d+AvOPuA*d9669wEZ6[NN[6ZEwj&FN3UmmU3NF&jO 3'&&'#3#'#' p   鳰 !p^-~J<<1X99Xt[F 3!#3#3':G^-~|{|[F( 33353##'Ń^^^-~t[F 353#5!#3'YYFYYO^-~|||l|[FJN2 "&&54632'2654&&#"''b=^5t\\tt\ %&^-~ Ql`vOZ''ZOv`F p!53366773'\(   )^-~(G&&G(P[FHN:%)3535&&5466323#5>54&#"'R)3]??\3)R$ %^-~w2wTUIIUTw2wj+GL1a__a1LG+j[F*N,"&546632373327#"&'#'2677&&#"Xl;`5,I  ,4>30 3/!7+ yRu?+8W9v&l %-Rx?,V,+CJHCHO.246632#"&'2654&#"'6654&#"H/aK7b>+*:O:Z0%O#b'8+*5),%'9Dl?'P?2J `FI^-&;t923'8k>*)'HDII$O1>54.'736673 9I*42)0 -D2$-"/9 "jGPZ?nn|L.f*5#!-"&&54667&&54632&&#"'32654&')BoC-I+-D]a:{8!9j)2W@3E# EF","&&54675&&546632&&#"327&#"3267JNuA>4./>nF5j+6 H$82d"$++63_+i^(VE&'6654&'.54675!#s0D&H;"=GE?hM)=4VI&'5T=_RttVa`((2 7:ZAO>54&#"#4&'336632&0 "M7VEN96(!%XS(T*6k]7! "&54632"3.2667#,nnnn,++, ^SOOS!VNNV!="&&55#5!3267HR!%+,+ H 2]?s3th%.# l IJ!34&'33>7&&'U&Yi= (I)DK"E# XT'?#]:a@$#1kb& &jD H8"@''&&#"'6632## 3  2-Wh!c '%w bnN@<I&3326733267#"&'##"&'@"!/ %19 >$% 5+")4:v*m./+- +H5 E-2ss/)"8t8-"% 0'Y3%"&&546632'2654&#",BqFFqBBqFFqB2002111 =uRSt==tSRu=wM@ALLA@M N""&54665#'665#57!#3267SAz bKR  & ]MJ\)Xc eRnt+bK l HO)46632#"&'2654#"H@nEp~=a6"FV'8\+81^x9wUx? 9l7FLJ?g/@ "&&54663!&&''2654&#"Al@Fp>(?'&);gA).-*(0/ ;qRVq7yV8Gh8wB=;T?H@G2&"&55#57!#3267YFJ > cRms=r+ n > "&&54654&'332654&'7&Nd/1%/1} 9dB!C!S(>#c/-/LR-g@9x;O?t#5.54667534&'668b;;b8|9a;;a9.&&.$.&&.=oOOo=}}=oOOo=CJ"IDDIJ)CD '7373'#w[ɑ~ V7 OEt%5.554&'3336654&'7N[(",{)* ol@h>{R)>#><*@ FQ2hB:|>B-"&54673254&'332654&&'7#"&'#O_,"%&-| !)XQ":4 >74>l>4A]"6++6"4)HC)BC'15yM#**#IF$'6654&'.54>32&&#"s&5*QC(/Pg79\C0?RJC>E&+ #8W><]@"# [H<=8#6)\H.)6".5546632'2654&#">54&#"G/[I,0cL5a=/)'?&?iD&6++:/#4R@B,*# <_DDk>&O?2O2M/G].0-(8  4=V%$2")'K9! ,7&&"&&54&'332667.546632.RAC/*/lMa,U*UwO-9b=Xy?z," hT/4V4"1 4\#\U -<>7X3XnO?tOA *6654&#"5.5467546632i'/{:b;:.b%%*-,N1PX<`8,Y-GJH>3?tSA4U/Y3:LZn2tSvA+U**N>&F">& AO>&=>&=&3%>&>>&>&B>&=>&J>>&JIDJ(34&'33>7'667&&'U&Yi= (I)DK"0,%GD" XT'?#]:a@$#1kb&#H= (W)&iC H80O( %2654&#"5.546632,42244223T1GsBBsG0Q3dPDALLADPBgDSt==tSCfC-U-JF!'6654&&'.546633&"#"r &)9iCKM(Z$>NBI>E&* 8_HUp7y>G.8#6)\tO !!3#tsaLS)K*'6654''7&&''7&'7 4h9< x[~'1^-~[Fh:>J(E"&533267gR?' [L.bZ!m 8#8#8!+b.>j-mi-jj-ls-i3Pn3Pkn=o7!Mh:>J;GN'6654&'7 $+\L&?:J9,)4.5467Z%@&L\+$4),9Jt'7<}[~'6654&'7'7 %LH$6<}:J90#1}.5467'77$IL$ ~<}1#09J7'6654&'7'7 %LH$6^}:J90#1.546777$IL% C}<1#09J&#"&&#"'66323267'6654&'7_! ?)%! ?){ & SAE8  3$  4#/  ;!%& #&&54677"&&#"'66323267O0EBR % ! ?)%! ?)&%!;  v  3$  4# OJ23!!32#'32654&##J[EqDBoE_P;:;;O|#SHJ\)s+..%J2l` DL 3#'53667>7!3#5! U % YO JBg%(9:\ev:Y^>\ܼ\W-3'&&#"'6632353376632&&#"####q   -C&x&B-   qB%x%B[.CC..,*"&'732654&##532654&#"'6632%B5N&S.6C=@WC>47,(B"K-r=tz*)1AEw ,1f#!.*)&m'#&"b(+^Q/K P;C[.@33373#5467#@88:4Dt:|6@C& ER33376632&&#"##E:L"S7 !;˞<D2#w"&'732667667!##G" [W 2C BGbbtE{Fmy0:@ &2@mK16:9F"&'7327733773( . ݜL64E_ ⾜JVH5&&5467534&'6lvvltlvvl`1/4/1` Z ~rq{ XX {qr~ ZU{ C>>C F@D^ 33333#5@K z\ܼ-!#"&&55332673-!Mo;:='.iXD6t: 333333OxOtD^3333333#5~KtK~; s\ܼ93#5!32#'32654##>h?M M>%;N$n@SNP `\$KT{IC^"3KtsGD"%26654&&#""&'##336632  I\12 [G]ees%]TTZ""ZTT]%~!5##&&54663335#"I8FDrELL:==^LNX%t`&001\~]\Na:""'732654&#"##5!#6632*  +$  %3Y6)F p631||+_NNY%l~&79"&&546632&&#"3#3267gUQTT?d!N8#;V SC(?NR GstK3"^CI{UJ$\`2'J JN; E#+"&'732667667!32###%32654##+   7U15[8|2!9%$'L 6;iZ(XHO^).VfFYh+,3UE3335332###732654&##V7U13V6V #!# (XHO^)u(7/&85!#6632#54#"##WhH  ||YeHER~&@~&FC& ?D 3333##5? zt<3#53533#32#'32654&##ww%GsEBqG*!8;:>u``u_"OBN\'r(2+%&2"&&546632"3&&267#,MwBBwMNvBBvN-; ;-/<; NnoKLnnN+KJJKNVRSUo33366776632&&#"ŜO  %NH y6e66e6\S#2l83!73!l 2 3#57!!3#~LLF(|KDe23'&&#"'6632353376632&&#"3#5####q   -C&x&B-   I6 b'B%x%B[.CC.\ܼ.D,,5&&'732654&##532654&#"'66323`)N&S.6C=@WC>47,(B"K-r=tz*)1AdP +&f#!.*)&m'#&"b(+^Q/K P;QbED]33376632&&#"3#5##E:L"S7 !;S s*<D2#w\ܼX3#5!37>32&"#"##13'3     ,p1|03$|@D^333533#5##@K pa\ܼ6D:5.546632&&#"3267!Bj?SW>d!Q7$E[]I#;Q7T S^lQ3 [pbdp YBHH35#57333667733#_BBrFq%I''I%KDU333667733#5#'&'#?   :vW p7G  DO={44{\ܼ0;3,D\!#"&&553326733#5~+Lm:8:&K {.iXD6\ܼ>*336632#54&#">+!Mn;8>'.hXD5J WC& OC& SM\C& 20@/&&2N&&2F/&Fy&=<-32654&#""&54>7667663291+*.(8kv.TsF.2@#4I-L*5W5B7# ګoT*  803fLLs?T##332#32654&##32654&##T;_8(,/8;b;gQ*$$)R^-%',]92;  623?/t3!!tsTF3#'53>77!3#5!n  uO~ 1J ׿` KF`7# V-3'&&#"'6632353376632&&#"#'##5#q  -C$p$C-  qA*p*A <);ii;)<0)"&'732654##53254&#"'6632=o;9)T"F>[xoS2>+H)62m=Hn=%375Dv *]0c/_!>2: 722E"I33366773#5467#I #  " %].;&\.=I&" MF33376632&#"#'#MN.I5 vO[?)  ; "&'73267667!##I  vo  R "(JJ}7o7SY%3#33366773#54667##'&&'#%; 7  6Q9  66OP!J LPOH 33353#5#H/)*H3!##Hȓ}HH)+C#2&3#5!#}ss>;4HB#/:57#"&546632'536632#"&'275&&#"32654&#"&CO*C%#|->J*D'$ ! K yQu> HL sUx? H$ DGIDFLCC%23HTI 33333#5HO~}`@!5#"&&55332753u(#>`6-4$'YJ.)#5 333333#IxI}}#T_3333333#5#FuF;q}}`33#5!32#'3254##&<`88`<&NN}s H>@L p<9&2 3332#'3254##3&$3Q00Q3$?? H>@L p<9Q* 3332#'3254##Qi?d::d?icVVc H>@L p<95"&'73267#53&&#"'66324m'7F#>R L:F2?g:NLI $V17c2+#U#9sXVt:D %2654&#""&'##336632!C^ 45]ATddk=PP>>PP=wec_a"!5##7&&54663335#"{Gm)97]9VVO'H:>G<$7#/)7#-<&*"&'7326654&&#"##57533#36632=%  ,*(BB H1\a9hl)j`MX$*EHGK,^-Et/&#C!"&&546632&&#"3#3267[PIPO9[!?;"8N R>%D4*j :tVWs:Y,1c71Y%5.O$ON*<%@ '"&'73267667!32###%3254##.    4S11S43 DJJ -GP H>@L }>}>EK|<9$?3335332##5#73254##$O6S//S6OCC𳳞 H>@L p<9IMF/&$I/&">;&- KT  3333##'K~} 2t3#53533#32#'3254##&@K p<9/)%K33366776632&&#"ֱK   EA ]%M''M%HXV|#x3!73#x w / 35#575!#3#SSEsrKTc23'&&#"'6632353376632&&#"3#5#'##5#q  -C$p$C-  @>a%A*p*A <);ii;)<`0T+'&&'732654##53254&#"'6632+S,9)T"F>[xoS2>+H)62m=Hn=%375bO ]0c/_!>2: 72=J MTR33376632&#"3#5#'#MN.I5 _Xl3vO[?)  ;`S3#5!376632&&#"#'#3 E0   h3}s[A' EHTI333533#5#5#HO~V`CT#'&&546632&#"3267YsPL;`D77@PN='A;B#hSt=&['LA@M] H953366773ǔP    P'F$$F' H85#57333667733#M'P    PnE'F$$F'[K%TA3'33667733#5#'&&'#%3    ,Za|#9   1P+,P~`R,+R@TJ!5#"&&5533267533#5h% <]5*1O}'UF('`H#V&  2 '=& Q7#& 7"I&"/)&(/)>;&->; &-//&e C$0"&&5467&&54667>7'32654&'%?f=]G+D5bB:@$C"CA!;%DL+; FQ4?Q4EQ4Ru)5AE"&''26533&&554632"#&&'#"&54632'2654&#"53 e  -1 a  -1JJ11II1J q{3[z1_@Cq/[z1_@COXWQQWXOZ"+,"",+"NNJ 2=6654&#""&&5467&&5466326673&''327&&' %D]0?*'I1JS%8=  , 3(#CG%Y}1( "@ %.'3U2AS&G/M/PD)A4; K+;n3 w."%.C$%8  '"&54632'26654&&#"7"&54632,nnnn 33 44,, ++ r(`RS\&&\SR`(*"#))#"*O{ 353#566733OAN%lwo[ w335>54&#"'66326633:[L62&?O2hICd9Aj>?TM}i-/1'O232[=5oo6|**"&'732654&춮&#"'6632Rv%D P+4C"SK^M2,%A!J/l=Ej;@9;S+#.{ 35467#5!533#$D PPkO6ne~p.{"&'732654&#"'!!632Rt'B I-6EB2, A (,;c32&&#"6632=< B%&;4*1\I+.Mc4Df M< 'C*"S$8X4?h%"L9161+$LwTYT)-X&WK!$*WCB_4>{3>7!5!+D20\W+|*N*"&'732654&춮&#"'6632Rv%D P+4C"SK^M2,%A!J/l=Ej;@9B >7!5!%NC$0%54&#"'66326633:\L62&?O2hICd9Aj>?TMk.47'O235`A6qp7|**"&'732654&춮&#"'6632Rv%D P+4C"SK^M2,%A!J/l=Ej;@932&&#"6632=< B%&;4*1\I+.Mc4Df M< 'C*#S$8X4?h."O>383.%NzV\V*.X([N!%+YECb4>3>7!5!+D3=K(R|x@|[Cz`=&3"&54675&&546632654&#"2654&&'+nG1(58a?_q5&2E8k"0.,#1G,8'D."B dO>jVI.51/8[Q_"'C'"'CY #"&546323"&546323"&54632[)33)*22)33))33*22*)33 8()77)(88()77)(88()77)(87'3"&546320+99++999-,88,-9R73"&54632`I+99++998,-99-,8b&7&>54&#"'6632"&54632+. * 0R$c;:\7!/.<+99++99(<.'& K(2$H7(7+)2#9-,88,-9gF&"&&54>'33267"&5463249]7!/.+. +1R$c5+99++99$H7(7+)2#(<.'& J(38,-99-,8/''3##/푑R/'{""&5467632-7>WX&48 (36"TLR}(ND02).7"'667#"&54632'48 (47)8=W"NE/3).7UKR}3"'{E"$'{E$'{"&&54632#"'gWW=8)73) 84"(}RKU7.)3/E%'57Z>77'7'7>>77*'{;.'{F~F~F~P675!PooX655!XooP675!PooX6e%"&&546632,.K++K./J++Je*I..I**I..I*vS%"&&546632'2654&#",4S//S45R//R5,77,+88S/R23Q//Q32R/K:..::..:r7!.r(`7!%35#R`LFzr753zrDZ`753%3'ZղY`xFT73DTd47377'yC4yYZzR%5!*dRDZ0%5!'7#*Y0x|T%%5%3DTY4%%5%3'5yF4\yZk7!'26654&&#"<*B&&B**B&&Bk6 %A))A%%A))A%XJ55!X<\5!<nn<5!5!< ^^^^>I5!>ISSc"&'732667,xg&A??A&g=?C$++$C?=M &&5467arraRYQQYV捍VAWwvW~M '6654&'7RYQQYRbqqAWvwWAV捍h!#3(\N@Nhh53#5!h(NNjh/"&546654&&'5>54&&54633#"33`Z<66<Z`M)>(/55/(>)=Q$53!V"36#Q=N*(O,93  39.L)*Nih/532654&54675&&54654&##532#i)>'.66.'>)M`Z<66<Z`N*)L.93  39,O(*N=Q#63"V!35$Q=J`3JI{fm3J`3{Ifm33낂H0H@[67'7'7737'@a N a@t[,DG++GD,Y 5'37' v Pv vY75'75'37'7' v P v ~~ v v ~~ v G1>"&'732654.5467&&54632&&#"654&&'7j"T3<&=C=&-% ^T:]D86'?E?'+) b 4=$6O(%T)+K3+A/&D)DU)\' -@-,A&C[!% ( 0 %"&&5466333 AnAAlA*44hLTb)9$w&Ȍt>'vD$=I7&>54&#"'6632"&54632&>54&#"'6632"&54632N %AJ'?V! 4+99++99 % AJ'?V! 4+99++99/G;7 TI>+@314!9-,88,-9 /G;7 TI>+@314!9-,88,-9<D$*6%&>54&#"'6632"&54632'3"&54632f % AJ'?V! 4+99++990+99++99/G;7 TI>+@314!9-,88,-9 9-,88,-9$*67&>54&#"'6632"&54632'3"&54632N %AJ'?V! 4+99++990+99++99/G;7 TI>+@314!9-,88,-9 9-,88,-9@(7''36654&#"'6632"&54632 v%<,&<Q(v'2#"&546q v%<,&<Q(v,3< DE,4"&&546632'26654&&#"'32##53254&##,LMMLLMMLAb66bAAb66b:+F)*F*< QghOOhgQ=D{RRyCCyRR{DWm901@[@e7)2"&&546632'2654&#"'532#'#532654&##+6Z66Z67Z55Z7?QQ??QQY#.*<74[;;[44[;;[41SFFSSFFS8 "M<7 8,") Bng""gT 5:6 ^<  *&);=   (%(? :^GG^`ss`m&/9".546632#'##"&&5466754&&#"32672675SnhCIK\ $!&0:".54>32#'##"&&5466754&#"32672675S#G<$=a6-;**U$F9*TW\T(;c<2#&?'6E' )?=eHTo6I[ $"F37#7#537#53733733#3##7#i hKW P\TiTOZT_Uhny^n^^n^T'7'7737'@R N R@e,8H H8,~|675!|`oo|6|6@'-3'7&&'77.54632237&&'#74&'27" W'L@3)N2wdX"7I*O47iM`JEs #dr)@1L[ $T h*A11P. a, Zl 2x2x 2l 2x 2l2l 2x2l 2l 2X2}X2ol2v 2: "&54632'2654&#",KbbKKbbK))**nbbllbbnR8FE66EF8F 535#566733ym08UiZCZF'6654&#"'6323Yf# -$=>aEUD89A]$!08QF>0S1Z:'"&'732654춮&#"'6632*7XA.&25*/!&= I1'B(B&+-I''3>7# 0"< 1#$6F53533##5Ok\_::_d6'ddGVV:"&'732654&#"'7!#6632*7WA.&. - %>&[''3" [79(:M: $"32654"&54632&&#"66321$)"4T]f[/:*$.01=G'C )$6p\^tD 71B9'>$F >7#5!2#:.3=_[4[::fkA:$0"&54675&&54632'6654&#"2654&',HX,%#!V=@SE()X7""/!"@."3*299293%.A  : %73267&&#""&'73267#"&546632!#(#%.=*%/.1=G'D*T\dQ )$D 71B9'?$q\]t&.54667J'11'O/))//U]<<]V.(?uA@v?}&'6654&'7P/))/P'00(?v@Au?(.V]<<]U=l "&54632,%%%%$%%$v'66'#"&54632&(''HA7 #"a9QD "&54632'2654&#",@TT@@TT@ \MNYYNM\O'33%%33'8!5#56673Q&*S@D356654&#"'66323>T>A(;G2\7)L#8$:3"AWD%"&'732654춮#"'6632-F#)-#& '#*E(2E#N B 7 >1(! &,8D7573533##5`LMA^33^=3XXB==8"&'732654&#"'73#6632."D#)++Յ 2;L B X#3..@D"%"3254"&546632&&#"66321 $GO%I6 7* &"'.6G ^I-M/= ."0..B8 3>7#5!&&(-HE'W8+MS5D$/"&54675&&54632'654&#"2654&',;K'J35I#K.  6% ! )22)  $$%6     D #%3267&&#""&'73267#"&54632%  #!6) &!'-6G6GO%I < -! 0./A^J,M/ &&5467B3993OS+(Y8xOOx70am7i/ '6654'7O)*SO399Y0/i7ma07xOOxlz "&54632,%%%% %&&%}vz'66'#"&54632&(''#%A8 $#3/9P+{ 77o 77{ 7+{ 77{7+o7+{77o7+{7+{777.l7v7o)oJo7o""&5467&#"'6632#'#'26752H)A>#8 o+#u2\L8P*T+1U o"&&546632&&#"3267[2P/4U1"50  '//$ )@o)M67M*@ 1)(1@oK "&546632'53#'#72675&&#" @L)A$&gT0 $ o\P6N*1t, T  )./+p"3&&"&&546632#3278*#3T10N-ON5%**"Gz (M74M+\B">wR5#5754632&&#"3#JJGO3#˾wk5#53"&54632&}7&&''wQv"$$"k7"&'732655#53"&546320 "~D)&&'' I  #Q(E*"$$"wK 3373#'hqr|pQ-w~~-QoK"&5#533267zC=E  &oL>QP0w"!3366326632#54&#"#54&#"0T.""- 2"73hhwJ+"J=˾ܾw336632#54&#"U5%83hwJ+I>˾o"&&546632'2654&#",,L//L,,L//L,  o)M67M**M76M)S1()11)(17336632#"&'72654#"U3>G)A%(4#8 !\L8P*3_+1U  %57#"&546632373'2675&&#"]-@L)A$*Q $ c0\P6N*">  )./+w336632&&#"V@# 6wJI)(W#,o&"&'732654&'.54632&&#",)T/504"PF+E/,0-5#Ro?  &/:=  %.>o""&55#57733#327mPBEJ W!"4oQAoMaaQn% J o"&553326753#'#83hhU5oH=.tw 3366773yh0  0cuwJ33&w337733773#''#xRf&S(_OxwIddddZZ|w7'3366773#'&&'#|oholioo"  w4  4447"&'7326773366773  h/  (ctCM@//@>w 57#5!3#w7Q7Qp "'7"3&&"&&546632#327:}Fl7*#3T10N-ON5%**"GnD (M74M+\B">p "'7"3&&"&&546632#32704kGv*#3T10N-ON5%**"G2D (M74M+\B">2"3&&"&5467#"&&546632#326732678*#'". 3T10N-ON5%("1  *z d""&(M74M+\B" =(/ p"&54673&&#"'6632'267#'OP/#)"G1N//M0&%p]C" >)M74M+N!!wN4632&&#"6632#54&#"CI. 5$83hwR:K L?H> %%"&54673366773'2654&'#/1:hh*  )ce91  6,- "" -,6@  wM5&&546632&&#"1@/M-3H3+ +3?w$I7.<"A!7$o"&546632373#'#72675&&#" >M)B%2& PT2 $!o\P6N))! T  )./++%"&'732677#"&546632373'2675&&#"H#3$#->M+B#,S\A %"C &\F2K)@D p )(')wk 535#533"&54632tfj&&''wQQQv"$$"ol'2@53بHH=5! AA>=5!>AA$?4S)7'7&547'76327'#"'72654&#"mIQ"!PIY0642YIQ"RIZ46/e$22$$22?JR.A?.RJZZJR-@!7RJ[ N5-,66,-5@ +773254.546753&&#"#5&&@@/W/J*CJC*XLb4MI#?)E*BKB*WSb1hsd!-*>.AV + T.)>.?])C&)356654'#57&&546632&&#"3#!C4BpT ;gB>Y#O,07#[P5 V)?\2*'P.0$[ $4|9{35#535#5333667733#3#⩩==F7F%!B !B F7F-G1"&'#57445447#576632&&#"3!3#3267}f?67Aj3_%Q4 2BD1#6Q(e vqD Eny(&O<8J  J8=L,0` !5&&5466753&'66757av8a>Q'?C$;E"%#$$)_ mGhB a]Z ]_\-A@.&&"&'7>77#5737>32&&#"3#!2  WK /VE; &'s'Q` l=9e+I[+ n+#7kY#O,07#[B,D  E ?\2*'P.0J  J*|<{#'+3'5#575#57533533#3##'#73'#'3'#3'# "*SFFFFTPjEEEETP #>10= zz626<2"">}Y5.59F;  ;C? - }##&C#5.5466753&&#"3275#53&Bf;9gCbU=Q4 AGK@#LI)nf P_\U he@Pqegm zx$f56"&5467#57367#5736654&#"'66323#3!327Gko\l Dt %(AH=)p gU  ED  O'0_RJ K  %<^((O3!5.5466753&&'67CGn?=nIQW@Q"+#Q!O/3.01nd Nb_T ][ AO Z (L$-eTklY {75327#573&&##5!#3##'YItQ F7I:MK H6uGDuJ#?J@Q'{ 5'75'75377>54&'7yD#gD#g##*H,yg @17!@2~E@V7E@V"8#  [|=#5{35'75'75#5!#77q#q#q#q#7@H77@Hkks7?I77?I#5{ 3#57!#5!gEKL1JJ9{!35#575#5732##3#32654&##mmmmClACm@=74::47E3D'&QAAR%2KU7.504{35#57!!3#3#LLݏaU|y{PZaGp7'77'7\K33KI/0IGphGphH' D&h F '3?K"&54632'2654&#"'%"&54632'2654&#""&54632'2654&#"6II67II7&X6II67II7-6JJ67II7H<''&'>H<''&'Q|' qD&hG|' qD&h Q' qD&hG|' qD&h G' qD&h G|' qD&h G' qD&hG' qD&hG'qD&hG|' qD&hG|'qD&hH|' qD&hG|' qD&hG' qD&hG|'qD&hG|'qD&hG|' qD&h5F{ !-5#56673'%5#56673"&54632'2654&#"Q&+S&@Q&+S6JJ67II7@,^]A H<''&'G' D&h F^6 75#53533#l^hhF~5!FhhTp# 7'7'77'IIIIpJJJJFIK "&54632"&54632%5!,"//"#..#"//"#..+""++""++""++""+hhF&tF-g'&ty%%5%~ fby75%5%5b fF0 35!5%5%F4̬hhzy."".F0 35!%5775''5F4hhy."".yzF6 75#53533#5!l̞hhhhV 3#''#Vvy.--.tF(l77#537#5!733#3!XGYIH]GYIH(zggzzggz4$%".#"'66323267/%$'X U./%$&XU)))NC(*)NC4v$&tF^~%5!5!^hF^~7!!F^ hI^D7546632#54&#"I;fBBf;l@77@^Gh::hGCHHCF^673!Fl`^hye(4%"&'##"&&5463236632%267&&#"%2654&#"5P)B.(A&ZI/A#L3-J,-N$( 4"&+$10y.@%/0M-^h,(5/2V7Fb3%!)0 ).$&./"&&546632'2654&#"-(B''B()A&&A)%%%%%A**A%%A**A%F)! )) !)c3/cKpc&vcr''3/c@<I< +73267&&#""&&5466324454&#"'6632.&A3*7=5Z57a>#D3;2@)Y4Ng4I+,>L!70X=Eh;  T`Z#'L[r_b""&'732654&&546632&#" 'QN  'Pj>GMRGoAk>GLSFpAp#46632&#"rQN &pGoAk>G}br"&'732653 'Pj>GqFpA!Y4'736673Jc bPEG**|9a9u O#33736677#O˰˜'(   t4m1<<1mB 35!5#535!5!B&|{|t,5,c'tAA;.{ 55!!!;⧮=xW"#W||?{!#!&x sH".:"&546632&&#"3267'77'7"&54632'2654&#"?T,G(2/  !! )9kK33K@TT@@TT@8WO6K(< 1)(/ =I/0I\MNYYNM\O'33%%33'J )6654&#""&''667546323267;,+6Cl  71jQJW*[H./5!T*X6 4IKZ~uZP>kd64,Y0>1".54>32!"32673!2554'&&#",9cK++Kc99cK+b6T5_"&(r G&(H 4\zFFz\44\zF <=3 7'7'%'7Sj S iG6 %%7'7'7S i6j Sf6 7'77ij S6T j 8 5!!!!#FN((N  ODU##UD97'3'#'##nO  ODU##UEEN((J '7!5!75'!5!'74EN((NEODU##UDO9733737*ODU##UDOFN((NFd%'7!'57!'7dM[[MM[$[MpIIn??nIIp>H,O44N,,N44O,6E43EE34Eu 7!%!!KGA lAK:- 7!667%!&&'73667!K9Z&A4["B.]#1R1_ lA'EO(K:RzMD=7p8cRp&&'73>7I5](=$f{CZd=UJ==>xݼEN_5-!"&&5466323'6654&'4!-N/ OG6195m&$<$ 0^<*P*,Qafj!"&&546632%#"&&546632b1 (E*"eT2 (E*"e&$<$ 716CC617 >1CO&3cR 99 Rc3&\#53... hiX!%#"&54>73#"&'#!5667C'9MCsXXsCM9'BUFhFU3'BF-OZxUUxZO-FB'3cR 99 Rc]x+7EMU%"&&546632'26654&&#"'"&546323"&54632"&'73267'254#"3254#",ZNNZZMMZDg::gDDg::g iAQ/ 9''9 /Q MXYMMYXMC;jFFj;;jFFj;' && '' && 'B9!!9B0Id'3;C%"&&5466322654&#"32654&#"267'#"''"54323"5432,THHTUHH:FO/VV/O0HRSHHSRH(&&&&&&&&@;@@;@%#.5463236632.EPOA'kS?TT?Sk'AOPE->02@\D_`7DD7`_D\@20>x"6BNV&&#"3262672654&#""&&54632#32654&#""&'6632672'&00 6XRN88ohgq6b@U~Eo;H7X3%j KUXhOPfWh)  03P6/?DNSIuE;VbjMG MJ7T/73  e+%.45-%+L53g%,:H%"&&5467&5467&&54>7'267!'66327&&#"66327&&#",nB-1%?1 ,30 1?%1-Bn9QPb# "" #@;0: ?6;  'O ;6? :0;@`5==5""A77A""A77x %;IW%"&54632'"&5463226654&#""&'&5467663266327&&#"66327&&#",[_gSSg_[Bh;xmmxJsAAsJA6q$aaAsVUA+D''D+AU\@mEDn@ja݁hI)Em@d 7%2654&#"'7&&'#5367'7675373#'#5&',5EE55EEIR bb PIQl RIQ bbPIR lF66FF66FIPhQIR mm QIO hRIS mm J3'377''#x>9--99-- QP{y]\yy\]#5 33%!5''##vg JDDJh/cwppwc""C 5254#56]]k\\ODDORDCSzC &546"3zk\\k]]SCDRODDA5&&546632&&#"1@/M-3H3+ +3?P%H7.=#@!6%t373'!<<'!%<Z%"&'573267O#?  &)87iQ9?E }1z/1/u1uAyx3ykP1/}1z/xb3Zkn=m;P< 85 >  24 .) ".:FR^jv"&54632'"&546323"&54632%"&54632!"&54632%"&54632!"&54632%"&54632!"&54632%"&54632"&54632'"&54632+|]ac] -RmmR+}1z/'72d1b~'7QNw_+b'7N!+1/'7&Hd1Hb~'7ANJ_.>'Xc#.u1'73'#8ll8}144\C'73'#@ZZ@h'oo'Tn=".#"'6632327n% \@:% \@=MK7MKfT"&&#"'66323267s#1$_G4$0%_FLDKEP5!(P]]/5!.^^P/< "&'73267,URT((()TQ<[B // B[< "&'73267,VTr rT "&54632,+77++77>1()33)(1d "&54632,(22((22/%%..%%/m; "&546323"&54632#--##--#--##--;."#..#".."#..#".tN "&546323"&54632** ** ** ))* )) ** )) *8'6654&'7 $, bP'?8:ZB5",v'6654&'7 $,]L&?: I1(",w<R "&'73267'"&54632,XYL6.-7LXY ,, ,,<[B$44$B[(!!**!!(x "&'73267'"&54632,QY H 9))9 H[Q ++ ++FC%%%%CFx(! )) !(8 "&54632'2654&#",ACCAACCA8=+*==*+=7~ "&54632'2654&#",3??32@@26--55--675 '7'7NXbGNXb5#,#,y'7'7Ie^AHd^"4"4uA'737l8}}8lA4\\4T'737Z@hh@Zn(TT(n$n63$bB5 '7'7lbXelbX5,#,9y'7'7z^dsz^e4"45 '6632&&#"TQVVQT)(((5B[[B 00M '6632&&#"PRJJRP*""*CFFC""2x"&54676326%.;<B &&22-.F0$ "8.5467W%@'Pb +%8,"5BZ2u'67#"&54632B &&&-;21$ "1-.F85#5353JuuTBGB533#TuuBGB>5#53Al>OG"'6654&'7- % m 2R;(, /15D"p &546"3pZLLZ$ $9//9653533UTUGhhG5#53#UUiFFi 5#53533#UUTUUBGBBGBf53GG  m '6654&'7 ;,"P=g;6(%318 &&5467ZP=g^ :-"8(%31; '6654&'73 ;,.2V&&g;iH " 31 '6654&'73 ;,.2V&&g;iH " 31"&546673326750A%S!!@21 4% / A"&5466733267:1D&Z! #;2. 5& 1 Jg73j$5!#5#Ln܎GGu nDJL%".#"'6632327%=3,\92&=2-\94DC4DD 526548$ $ZLL769//9*53353LnL֎GG 5!'35#nn6Jk '&32366324&#"#54&#"St'  (<8SF OP /6 '7'77'1??1AA1??1A6,89,77,98,7n=fT("&5533267b=2j E:" O0C(5!^^cJ '6632.#"w&gxxg&A??JC?==?C%**;r "&546323"&54632''7########8NN;$$$$$$$$$4 "&546323"&54632''7""####""?_\$##$$##$}'9h:> "&5463277"&54632####;&hM{####H! !! !;r "&546323"&54632''7########dNN;$$$$$$$$u4 "&546323"&54632''7""####""|\_$##$$##$}9o7! "&54632'77"&54632!!!!_Ig#R!!!!H;G ,"&546323"&54632'"&&#"'6632327########E +! @2&!*! @3;$$$$$$$$88'79;9 "&546323"&54632%5!########(;$$$$$$$$EE "&546323"&54632%5!""####"".$##$$##$EE;i "&546323"&54632''737########\0dd0\;$$$$$$$$\,AA,\ "&546323"&54632''737""####""\;^^;\$##$$##$f'II'f6A) '73'#7'7/]t]/f8ON64\\4A,3- '73'#7'7;Z~Z;\,d1'dd'H2V<6) '73'#''7/]t]/fiNS64\\4Aw4/ '73'#''7;Z~Z;\e0a'dd'HM;W6*2'73'#7'6654&'7/]t]/f &RA 464\\4A 2 >*# &)'73'#'6654&'7;Z~Z;\ & S@C'dd'H/ <-!,'6F'73'#7"&&#"'632327/]t]/f<&C N%C 64TT48^&o&o'73'#7"&&#"'6632327;Z~Z;\>(F0*'F0'\\'?Z&96' 96<t "&'73267''7,URK-+,,KQM@]W<[B$44$B[,A "&'73267''7,JRH.%%/HR9H_\FC#''#CFl/9<t "&'73267''7,URK-+,,KQ_tW]<[B$44$B[xA "&'73267''7,JRH.%%/HR[s\_FC#''#CFl9<y "&'73267''6654&'7,URK-+,,KQy 'SCF<[B$44$B[}3 P4+1' "&'73267''6654&'7,JRH.%%/HRj &R@CFC#''#CFm/ =-!,'<E !"&'73267'"&&#"'6632327,NGH%((%HH&K3)% K32  2>'96' 864B'73'#7"&'732674RtR4VA;6!%& 6;4!YY!=^:((:'73'#7"&'732678W~W8\ILG&()%GK'\\'H]<1  1<Pn5!''7(1<P]]y犊K %3!3w>jq33犊,,j!!,,^5!5!Eq퉉^p3!3qdpxxp %!#!!!Ԋ,^^pq ##!#q?pw^p !#!##!J?,qdwpq #!5!5!5!q,ppq ###5!q?pwwp #!5!##5!J?퉣,pv^ 73!!!,,^^ 73333^w^^ 333!qqw^q %!5!5!5!3qJ,,^ %!53333ww^ !533!5!3ԣqvp %!#3!!!Ԋ,,^x^p 3##33^pxwx^p 333##!^,pxwwpq #!5!5!5!3q,,pp 3!##533q퉣pxwwp 3!533##5!qԣ,pxp 5!!#!5!EԊqpq ###5!#qpwwp 5!##!##5!E⣉,J,qw^ !5!3!5!,,qd %!533333ww^ 33!!5335!qJԣqwvp%!#!5!5!5!3!!!Ԋ,,,,^p###533333#qpwwwwp 33!!533##!##5!qJԣ,J,qwvwpq4>33#"9fLEE@i>pMf9>i@ppqq!#4&&##532q>i@EEMf9p@i>9fq##532665q9fMEE@i>pLf9>i@333#".>i@EELf9Xp@i>9fX3# LLX#5L LX#5533 LLLAAAAqq'5!E犊q73q75!犊pqq3pq'!E7!7!pq!p%!5!5!5!J,DDp!333DDpw%!!!!J,DDp%###!DDw,X!X,DpX5!XppX!Xp^pX}!Xp pX,!XpDpX!XpkpX!XppX9!Xp7pX!Xpxp ! pxp!pxpw!wpxp,!,pxp3pxp3pxpK3Kpx,pX!,,px*X #/;GS_kw+7CO[gs4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&8      8      8      8      8      8      8      U      ZU      ZU      ZU      ZU      ZU      ZU      *L* #/;GS_kw+7CO[gs4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&    >    >    >    >    >    >    >   NU   NU   NU   NU   NU   NU   N*:E #/;GS_kw+7CO[gs4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&/""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    "//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   9X5!X9 pX3 Kpxp,,!,pD,pX,!,,pD,,!,,DpX!!,,pxDDpX!!,,,DDDpX!!!XX,DxpX!!!XXp,,X!,,,DpX!!,,,,DDDpX!!!X,,p5-jB'3#57546632&#"3#33"&54632IBB$PC4ZZJ+77++77}m5V4 l !&s>1()33)(1 Z'"&533267%#57546632&#"3#L;  $#BB$PC4ZZ [K#m }m5V4 l !&s>z$#4>55#7#3ϑ"8CC8"op"8CD8"H_?,)4MAB>9 0?@>AB>9 gV 8  A 70A5G:0<8A00<A:89 JA:>@>?8A=K9 A:>@>?8A=K9 A:>@>?8A=K9 A5@1A:89 1:8@8;;8G5A:0O :@0B:0 []70G5@:=CBK9 =>;L [0]B8?>3@0DA:89 45D8A [-]B8?>3@0DA:0O 72574>G:0 [*]70G5@:=CBK9 7=0: 4>;;0@0 [$]B8?>3@0DA:85 70<5AB8B5;8 [-,*]?@>AB>9 0, A:>@>?8A=K9 A5@1A:89 1, ?@>AB>9 g, A:>@>?8A=K9 A00<A:89 J, A:>@>?8A=K9 2 $%&'()*+,-./0123456789:;<=DEFGHIJKLMNOPQRSTUVWXYZ[\]bc     de !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRfSTUVgWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~hjikmlnoqprsutvwxzy{}|      !"#$%&~'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ "      B >@^`_?  !"#$%&'(#)*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !AaC      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-.AmacronAbreve Aringacuteuni01CDAogonekuni1EA0uni1EA2uni1EA4uni1EA6uni1EA8uni1EAAuni1EACuni1EAEuni1EB0uni1EB2uni1EB4uni1EB6AEacuteuni01E2uni0243uni1E06 Ccircumflex CdotaccentDcaronuni1E0Cuni1E0Euni1E10Dcroatuni018AEcaronEmacronEbreve EdotaccentEogonekuni1EB8uni1EBAuni1EBCuni1EBEuni1EC0uni1EC2uni1EC4uni1EC6uni1E16uni01F4 Gcircumflex Gdotaccentuni0122Gcaronuni1E20 uni00470303uni0193 Hcircumflexuni1E26uni1E24uni1E28uni1E2AHbarItildeImacronuni01CFIogonekuni1EC8uni1ECAIbreve Jcircumflexuni0136uni1E32uni1E34LacuteLcaronuni013Buni1E36uni1E38uni1E3ALdotuni1E3Euni1E40uni1E42Nacuteuni01F8Ncaronuni0145uni1E44uni1E46uni1E48Omacron OhungarumlautObreveuni01D1uni01EAuni1ECCuni1ECEuni1ED0uni1ED2uni1ED4uni1ED6uni1ED8Ohornuni1EDAuni1EDCuni1EDEuni1EE0uni1EE2uni1E52 OslashacuteRacuteRcaronuni1E58uni0156uni1E5Auni1E5Cuni1E5ESacute Scircumflexuni1E66uni015Euni0218uni1E60uni1E62uni1E9ETcaronuni0162uni021Auni1E6Cuni1E6ETbarUtildeUmacronUbreveUring Uhungarumlautuni01D3Uogonekuni01D5uni01D7uni01D9uni01DBuni1EE4uni1EE6Uhornuni1EE8uni1EEAuni1EECuni1EEEuni1EF0uni1E7EWgraveWacute Wcircumflex WdieresisYgrave Ycircumflexuni1E8Euni1EF4uni1EF6uni1EF8Zacute Zdotaccentuni1E90uni1E92uni1E94uni018FEngIJuni004C00B7004C uni01320301amacronabreve aringacuteuni01CEaogonekuni1EA1uni1EA3uni1EA5uni1EA7uni1EA9uni1EABuni1EADuni1EAFuni1EB1uni1EB3uni1EB5uni1EB7aeacuteuni01E3uni0180uni1E07 ccircumflex cdotaccentdcaronuni1E0Duni1E0Funi1E11ecaronemacronebreveeogonek edotaccentuni1EB9uni1EBBuni1EBDuni1EBFuni1EC1uni1EC3uni1EC5uni1EC7uni1E17uni01F5 gcircumflex gdotaccentuni0123gcaronuni1E21 uni00670303 hcircumflexuni1E27uni1E25uni1E96uni1E29uni1E2Bhbaritildeimacronuni01D0iogonekuni1EC9uni1ECBibreve jcircumflexuni0137uni1E33uni1E35 kgreenlandiclacutelcaronuni013Cuni1E37uni1E39uni1E3Bldotuni1E3Funi1E41uni1E43nacuteuni01F9ncaronuni0146uni1E45uni1E47uni1E49 napostropheomacron ohungarumlautuni01D2uni01EBuni1ECDuni1ECFuni1ED1uni1ED3uni1ED5uni1ED7uni1ED9obreveuni1E53ohornuni1EDBuni1EDDuni1EDFuni1EE1uni1EE3 oslashacuteracuteuni0157rcaronuni1E59uni1E5Buni1E5Duni1E5Fsacute scircumflexuni1E67uni015Funi0219uni1E61uni1E63longstcaronuni0163uni021Buni1E6Duni1E6Funi1E97tbarutildeumacronubreveuring uhungarumlautuni01D4uogonekuni01D6uni01D8uni01DAuni01DCuni1EE5uni1EE7uhornuni1EE9uni1EEBuni1EEDuni1EEFuni1EF1uni1E7Fwgravewacute wcircumflex wdieresisygrave ycircumflexuni1E8Funi1EF5uni1EF7uni1EF9zacute zdotaccentuni1E91uni1E93uni1E95enguni0237ijuni006C00B7006C uni01330301uni0250uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0251uni0299uni0259uni025Auni025Buni025Cuni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni029Cuni0268uni026Auni029Duni029Euni026Buni026Cuni026Duni026Euni029Funi026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0278uni0279uni027Auni027Buni027Duni027Euni0280uni0281uni0282uni0283uni0284uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni02A4uni02A6uni02A7uni0294uni0295uni02A1uni02A2uni01C2uni0298 uni014A.aa.aagrave.aaacute.a acircumflex.aatilde.a adieresis.a amacron.aabreve.aaring.a aringacute.a uni01CE.a uni1EA1.a uni1EA3.a uni1EA5.a uni1EA7.a uni1EA9.a uni1EAB.a uni1EAD.a uni1EAF.a uni1EB1.a uni1EB3.a uni1EB5.a uni1EB7.a aogonek.ag.a uni01F5.a gcircumflex.agbreve.a gdotaccent.a uni0123.agcaron.a uni1E21.a uni00670303.ai.a dotlessi.aigrave.aiacute.a icircumflex.aitilde.a idieresis.a imacron.a uni01D0.a iogonek.a uni1EC9.a uni1ECB.a uni012D.a uni0268.a iogonek.d iogonek.da uni0268.d uni0268.da uni029D.dl.alacute.alcaron.a uni013C.a uni1E37.a uni1E39.a uni1E3B.alslash.aldot.auni006C00B7006C.a uni026B.a uni026C.aAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9 Alphatonos EpsilontonosEtatonos Iotatonos Iotadieresis Omicrontonos UpsilontonosUpsilondieresis Omegatonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigmatauupsilonphichipsiomegauni03C2uni03D0uni03D1uni03D5phi.a alphatonos epsilontonosetatonos iotatonos iotadieresis omicrontonos upsilontonosupsilondieresis omegatonosiotadieresistonosupsilondieresistonosuni03D7uni03D9uni03DBuni03DDuni03E1uni037E anoteleia anoteleia.capuni0374uni0375tonos tonos.cap dieresistonosuni037Auni1FBEuni1FBDuni1FBFuni1FFEuni1FEFuni1FFDuni1FCDuni1FDDuni1FCEuni1FDEuni1FCFuni1FDFuni1FC0uni1FEDuni1FEEuni1FC1 uni1FBD.cap uni1FFE.cap uni1FEF.cap uni1FFD.cap uni1FCD.cap uni1FDD.cap uni1FCE.cap uni1FDE.cap uni1FCF.cap uni1FDF.capuni0410uni0411uni0412uni0413uni0414uni0415uni0416uni0417uni0418uni0419uni041Auni041Buni041Cuni041Duni041Euni041Funi0420uni0421uni0422uni0423uni0424uni0425uni0426uni0427uni0428uni0429uni042Auni042Buni042Cuni042Duni042Euni042Funi0400uni0401uni0402uni0403uni0404uni0405uni0406uni0407uni0408uni0409uni040Auni040Buni040Cuni040Duni040Euni040Funi0462uni0472uni0474uni0490uni0492uni0496uni0498uni049Auni04A0uni04A2uni04AAuni04AEuni04B0uni04B2uni04B6uni04BAuni04C0uni04C1uni04D0uni04D4uni04D6uni04D8uni04E2uni04E6uni04E8uni04EEuni04F2uni0430uni0431uni0432uni0433uni0434uni0435uni0436uni0437uni0438uni0439uni043Auni043Buni043Cuni043Duni043Euni043Funi0440uni0441uni0442uni0443uni0444uni0445uni0446uni0447uni0448uni0449uni044Auni044Buni044Cuni044Duni044Euni044Funi0450uni0451uni0452uni0453uni0454uni0455uni0456uni0457uni0458uni0459uni045Auni045Buni045Cuni045Duni045Euni045Funi0463uni0473uni0475uni0491uni0493uni0497uni0499uni049Buni04A1uni04A3uni04ABuni04AFuni04B1uni04B3uni04B7uni04BBuni04C2uni04CFuni04D1uni04D5uni04D7uni04D9uni04E3uni04E7uni04E9uni04EFuni04F3 uni0430.a uni04D1.a uni0431.srb uni0456.a uni0457.a uni04CF.auni2116zero.aone.a zero.onumone.onumtwo.onum three.onum four.onum five.onumsix.onum seven.onum eight.onum nine.onumzero.bone.bzero.capone.captwo.cap three.capfour.capfive.capsix.cap seven.cap eight.capnine.capzero.cone.c quotereverseduni00ADuni2010 figuredashuni2015uni25E6uni25AAuni25ABuni25B4uni25B5uni25B8uni25B9uni25BEuni25BFuni25C2uni25C3 invbullet filledrect underscoredbluni203Euni203Funi2016 exclamdbluni2047uni2049uni2048uni203Duni2E18uni231Cuni231Duni231Euni231Funi27E6uni27E7uni2E22uni2E23uni2E24uni2E25uni2117uni2120at.case asterisk.ahyphen.a uni00AD.a uni2010.adollar.a zero.supsone.supstwo.sups three.sups four.sups five.supssix.sups seven.sups eight.sups nine.supsparenleft.supsparenright.sups period.sups comma.sups zero.subsone.substwo.subs three.subs four.subs five.subssix.subs seven.subs eight.subs nine.subsparenleft.subsparenright.subs period.subs comma.subs zero.dnomone.dnomtwo.dnom three.dnom four.dnom five.dnomsix.dnom seven.dnom eight.dnom nine.dnomparenleft.dnomparenright.dnom period.dnom comma.dnom zero.numrone.numrtwo.numr three.numr four.numr five.numrsix.numr seven.numr eight.numr nine.numrparenleft.numrparenright.numr period.numr comma.numr ordfeminine.aa.supsb.supsc.supsd.supse.supsf.supsg.supsh.supsi.supsj.supsk.supsl.supsm.supsn.supso.supsp.supsq.supsr.supss.supst.supsu.supsv.supsw.supsx.supsy.supsz.sups egrave.sups eacute.sups eogonek.sups uni0259.sups uni0266.supsuni02E0uni02E4a.supag.supai.supa colon.sups hyphen.sups endash.sups emdash.supsEurouni0192 colonmonetarylirauni20A6pesetauni20A9donguni20B1uni20B2uni20B4uni20B5uni20B9uni20BAuni20AEuni20B8uni20BDuni2215 slash.fraconethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215Auni2150 oneeighth threeeighths fiveeighths seveneighthsuni2151uni2152uni2189uni2219 equivalence revlogicalnot intersection orthogonaluni2032uni2033uni2035uni00B5 integraltp integralbtuni2206uni2126uni2200uni2203uni2237uni2105uni2113 estimateduni2190arrowupuni2192 arrowdownuni2196uni2197uni2198uni2199uni21D0uni21D1uni21D2uni21D3 arrowboth arrowupdn arrowupdnbseuni25CFuni25CBuni25A0uni25A1uni2752uni25C6triagupuni25B3uni25B6uni25B7triagdnuni25BDuni25C0uni25C1triagrttriaglf invcircleuni25C9uni2610uni2611uni2713 musicalnotemusicalnotedblheartclubdiamondspade smileface invsmilefaceuni2764uni2615u1F4A9u1F916u1F512femalemalesunhouseuni02B9uni02BBuni02BCuni02BEuni02BFuni02C1uni02D0uni02D1uni02DEuni02C8uni02C9uni02CAuni02CBuni02CCuni25CCuni0300 uni0300.capuni0340uni0301 uni0301.cap uni0301.guni0302 uni0302.capuni0303 uni0303.capuni0304 uni0304.capuni0305 uni0305.capuni0306 uni0306.c uni0306.cap uni0306.ccapuni0307 uni0307.capuni0308 uni0308.capuni0309 uni0309.capuni0310 uni0310.capuni030A uni030A.capuni030B uni030B.capuni030C uni030C.cap uni030C.auni030F uni030F.capuni0311 uni0311.capuni0312 uni0312.guni0313uni0343uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320uni0323uni0324uni0325uni0326 uni0326.auni0327 uni0327.capuni0328 uni0328.capuni0329uni032Auni032Cuni032Euni032Funi0330uni0331uni0334uni0339uni033Auni033Buni033Cuni033Duni0342 uni0342.capuni0345uni035Funi0361 uni03080301uni03080301.cap uni03080301.g uni03080300uni03080300.cap uni03080300.g uni03080303 uni03080304uni03080304.cap uni0308030Cuni0308030C.cap uni03020301uni03020301.cap uni03020300uni03020300.cap uni03020309uni03020309.cap uni03020303uni03020303.cap uni03060301uni03060301.cap uni03060300uni03060300.cap uni03060309uni03060309.cap uni03060303uni03060303.cap uni03020306uni03020306.cap uni03040301uni03040301.cap uni030C0307uni030C0307.cap uni03120301 uni03120300 uni03120303 uni03130301 uni03130300 uni03130303uni00A0uni2007 space.frac nbspace.fracuni2500uni2501uni2502uni2503uni2504uni2505uni2506uni2507uni2508uni2509uni250Auni250Buni250Cuni250Duni250Euni250Funi2510uni2511uni2512uni2513uni2514uni2515uni2516uni2517uni2518uni2519uni251Auni251Buni251Cuni251Duni251Euni251Funi2520uni2521uni2522uni2523uni2524uni2525uni2526uni2527uni2528uni2529uni252Auni252Buni252Cuni252Duni252Euni252Funi2530uni2531uni2532uni2533uni2534uni2535uni2536uni2537uni2538uni2539uni253Auni253Buni253Cuni253Duni253Euni253Funi2540uni2541uni2542uni2543uni2544uni2545uni2546uni2547uni2548uni2549uni254Auni254Buni254Cuni254Duni254Euni254Funi2550uni2551uni2552uni2553uni2554uni2555uni2556uni2557uni2558uni2559uni255Auni255Buni255Cuni255Duni255Euni255Funi2560uni2561uni2562uni2563uni2564uni2565uni2566uni2567uni2568uni2569uni256Auni256Buni256Cuni256Duni256Euni256Funi2570uni2571uni2572uni2573uni2574uni2575uni2576uni2577uni2578uni2579uni257Auni257Buni257Cuni257Duni257Euni257Funi2580uni2581uni2582uni2583uni2584uni2585uni2586uni2587uni2588uni2589uni258Auni258Buni258Cuni258Duni258Euni258Funi2590uni2591uni2592uni2593uni2594uni2595uni2596uni2597uni2598uni2599uni259Auni259Buni259Cuni259Duni259Euni259Funi202FuniFEFFu1F3B5u1F3B6f_if_luniE0A0uniE0A1uniE0A2uniE0B0uniE0B1uniE0B2uniE0B3ideoromnDFLTcyrlgreklatn V t  !!""#')13577::==@@MM[[^^eevv    $$**00??BBQQUU\\aassww    ##&&56;;?@HHLNQRYY\^bbddffllnnqquu  $%'-0146KLeeEHn#11BDHn (DFLTcyrl.grekXlatnl SRB  ! " #ATH &NSM 6SKS F $ %&'(ccmpccmpccmpccmp ccmpccmpccmp"ccmp*frac2frac8frac>fracDfracJfracPfracVfrac\markbmarkvmarkmarkmarkmarkmarkmarkmkmkmkmkmkmkmkmkmkmkmkmk mkmk&mkmk,size2size6size:size>sizeBsizeFsizeJsizeN                 d&.8BJT\dlt|vxzh z   `  P  t     8   & ^ ^ \ |  ZSx~xxxxxxxxxrrr x&,xxx2xx8rr8 >DJPV\bhnrrtzzrr rrrrh88xxxxxx  rx"(x.x4"x.x&x:@FrrrrLRrXrhr,,aCMJHB@1-?@VY;C4`8(H)vY>"T6R%'r*Pf3d)J ,.9EEEGBL$>F4OD\& Z `   , D L hh.djpv|^^^^^  ^,WBO1@V'b>7w6NMx jZZZZZZZZZZZZZZZZZZZZZZZ} &,28>DJPV\Vbhntz&VbnzhDDV2Jbn ""(.4:@FLRX^2V       >d,U*DCEO@0-86T4%Y3o2333q9 37L".D3h<3(*3B,$I33o3n3N 3W343-3633Vyq3$RK3  ,ZoJo ",z HHDJ>>>>PV>\bDDDJ>hPPPnV>JJJJtt>,`!6L2 ZShnhhnhhnhnhnhnhhnnhnhnhnhnhnhnhnhnhnhhhhhhhnhnhhnhhhnhnhnhnhnhnhnhnhnhnhnhnhnhhhhhh &&,28822>DJP,,,,,,,,#,,GF,!#$%&'/(a #"%+,4 hjFGE JJJMMKinLR# 11(BD)Hn, !#$%&')*+,-./01345@M[e QUaw    56?@HLMNQRY\]^bdflnqu $%'()*+,-01456KLe&23. !#$')*-./035MU?@LRY\]$%(06< >AEE} !#$%&')*+,-./01345M[Ua    6?@LQRY\]^du= 'R'*45 $*047:=^ *Us #&?@     DFLTcyrlfgreklatnR! (08@HPX`hpx SRB T" !)19AIQYaiqy" "*2:BJRZbjrz" #+3;CKS[cks{ATH ^NSM SKS ! $,4<DLT\dlt| ! %-5=EMU]emu} "&.6>FNV^fnv~ "'/7?GOW_gow  casePcaseVcase\casebcasehcasencasetcasezccmpccmpccmpccmpccmpccmpccmpccmpcv01cv01cv01cv01cv01cv01cv01cv01cv02 cv02&cv02,cv022cv028cv02>cv02Dcv02Jcv04Pcv04Vcv04\cv04bcv04hcv04ncv04tcv04zcv06cv06cv06cv06cv06cv06cv06cv06cv07cv07cv07cv07cv07cv07cv07cv07cv08cv08cv08cv08cv08cv08cv08cv08 cv09cv09cv09cv09"cv09(cv09.cv094cv09:cv10@cv10Fcv10Lcv10Rcv10Xcv10^cv10dcv10jcv11pcv11vcv11|cv11cv11cv11cv11cv11cv12cv12cv12cv12cv12cv12cv12cv12cv14cv14cv14cv14cv14cv14cv14cv14cv15 cv15 cv15 cv15 cv15 cv15 cv15 $cv15 *cv16 0cv16 6cv16 ss06 Dss06 Jss07 Pss07 Vss07 \ss07 bss07 hss07 nss07 tss07 zsubs subs subs subs subs subs subs subs sups sups sups sups sups sups sups sups zerozerozero zerozerozerozero$zero*        @:4.(" ~xrltnhb\VPJRLF@:4.(0*$ ~ztnhb\                                  ~tj`VPJD>82,&$              $JRZbjr~&.6>FNV^fn,*0.,z 2<x Vh!#L  &,28>DJP  ** U!!":d $USYc W $][a_aC$*06<KMHJNOQNC &,jjiikkC &,mmllnnC,6@JT`jt~@4e4v4 44 4$04 B?2Q4'\w44;2*v"d" !$%"#    ###)*+,-./0123456789:;<=>?@ABCDEFGrMNOP N R9  35CILPRTVXZ\^`bdfP !"#$%&'(5)*+,-./01234ef'J: 6789:;<=>K6 ?RABCDEFGHIJK@STUVWXYZ[L\]NPhijL4444 8C<<< < @ M4N4*(UMOQNP  35CILPRTVXZ\^`bdf(q    r "   _b+.qtA_+q b.tA$4   CHKOQSUWY[]_ace?$%QHL !#  "$'*/06 6Y[[>]x?zz[|\^~!   24CHKOQSUWY[]_ace!  35CILPRTVXZ\^`bdfmv  !o hj% qr5)*00mv9mnopqrstuvxyz{|}~   24CHKOQSUWY[]_ace\\&&))"";B//  $'JKLMNOPQRSTU[\]^_`abMO@A[1myRnnz$?($%QHL   24CHKOQSUWY[]_ace%ooPK!՞ww2generator/template/darkfish/fonts/Lato-Regular.ttfnu[ DSIGwGPOS,KGSUBV.TLOS/2ٮiM`cmapRԟNPcvt 'm`8fpgm zAm gaspmXglyf*~ʙS8Bheade|6hhea$hmtx[`TkernlBjT,lloca.V,maxp< X< name $X\^post:]iprepx9w, 0JDFLTlatnkernkernJnv$R ^ h B l  & rjZjL*|DV: !.!##L#$4$~%&J'$'()*+f+,6,-.(./t//0:0|2"233T334&4l455b566L667B778889d99:&::;@<=>j?,?@hABCzDEFG*GHfIK JNJ#$J&*2490:0<?0DFGHRTmNoNyN}NJJJJJJJJNNNNNJK JNJ#$J&*2490:0<?0DFGHRTmNoNyN}NJJJJJJJJNNNNNJ"#&*24FGHRTK JNJ#$J&*2490:0<?0DFGHRTmNoNyN}NJJJJJJJJNNNNNJ-  x#&*247L9L:?DEHIKNPQRSUYZ[\^lmoprtuy{|} 8DFLTlatncase&case,liga2liga8sups>supsD,>B      @ LO,{tu CjqvIxxxP`KtyPL@Jz  &   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ardeixpkvjsgwl|cnm}byqz`T@ ~1DS[a~    " & 0 : D !"!&"""""""+"H"`"e%&i 1ARZ`x    & 0 9 D !"!&"""""""+"H"`"d%&i{uq[H$I޸ޡޞ:ڜ`T@ ~1DS[a~    " & 0 : D !"!&"""""""+"H"`"e%&i 1ARZ`x    & 0 9 D !"!&"""""""+"H"`"d%&i{uq[H$I޸ޡޞ:ڜ-%59=J@GBhf[[ Q CQ D=<($#*$ +>32#'&>54&#"#"'4632#"&!!7!!9DO.?gI)-60#z -70 I9)8(  c>0((0>22cu&#@[87P;+&%iu"3+(.:(3</@)(?g6, !&@#Q CSD +#.54>32#". y +!..""..!-VW[44[WV-<."".-""- ,@) BQ D   $+#"&/!#"&/3ޛ ## "ޛ ## "6Q>BH@E  Y  C Q C DBA@?>>86530/*(##!#!+#"&5467#+#"&546?3#7>;>;3323+32%3#TQ GG-OUA $'H+PTTO!I %&A AY"Z% 9FJf"ZK 9Fj$g8CN~@J( I>) ? 4BK PX@$hfSCSD@$hfSCSDY#&#&+.'7>32.54>?>;#".'+4.'>yH50FaD%FkA9mh Bi<+):L1!HpE324.#"32>>;+#".54>324.#"32>4Wt?DsV00VsDCuU11A%%A00A%%A1  54Ws?DsV00VsDCtV01A%%A00A%%A1?T[00[TV\00\VB\;;\BA[99[w RT[00[TV\00\VB]::]BAZ99ZRx?K@8IH+%BKPX@*hSCS CS D@(hSCS CSDY@FD/-(&"  ??+2#"&'.#">7>;#"&/#".54>7.54>3267O_7o 1E.2P9"6&&-nFB,$^PyJ/SrD=:5d0Nd4pDYjk3To<8. 9M-#@AE&]CJsa[j6g]F}jTMNI_7AcD#RD93 @ BQ D $+#"&/3ޛ ## " (+.54>7!nh OKiAAiKO  imum 0szyt1lJ (+4'&546?'.54676*mi  OKiAAiKO hnu1tyzs0 `_0J@-)($  BKPX@ QD@MQEY@ 00+5467'767./7.=3>?'.'b!,$%#,# X ,!!, _"cKd eKd %) cKd  eKd !'d" ,@)MYQE +!!#!5!ikUR^P@?S D$+74>32'&547>7#".^,/0G-    *{)'3-a_Z&   %0:!!-d R@MQE+!!dXQ@SD($+74>32#".X!..""..!n."".-""- @kD#"++>;7KY 0!K#" "<L'@SCSD((($+#".54>324.#"32>LQmnPPnmQ7]zBBz\77\zBBz]7̼XXXX켤߈;;ߤވ;;*@' Bh CR D&+%!47#"&/3!!4  8,- Mqh$3;@8/ BhSCQ D,*$" 33+2>3!2!5467>54.#"#"&/>Y[sB0Rk<(R&"D9^C$(F^66\G1   ]P{6g^P}u=~ "l=(:klo??_> 9N/bf5l.JU@RF Bhh[SCSDCA;910/.&$JJ +2#".'763232>54.#5>54.#"#"&/>l[o>#A\9KcrpHL(DeKKqK&Qp[R%'D]66\G0   ]P{4`SDkQ8%co;9dP  I@,1N`/:`F(&B\8>\< 9O.bf5(`&@#B[ C D!#+3+#!"&/3467!fy[< ;l.@@=,+Bh[Q CSD(#&(""+#!632#".'763232>54.#"'!09>Bp_pt;Pm?tdV!63HaCKxU.'OvO6t>ptK&1Bt]rF*6L&0Y|MClL*!l2.2@/B[ CSD+)! +2#".5467>;>32>54.#"VtDHml|CT[k2 3|(MoGHtS-,PpCHtQ+n9mfc~HEp^z#'LErR-.RpBFqO*1Smn<@Q C D$'++>7!"&=< .'Z P",S%*y`&3GD@AB[SCSD54! ?=4G5G+) 3!3 +".5467.54>32'2>54.#"2>54.#"CkFqs>rbar>tpGkFoM)1Sl;;lS1)MoFFc>!Aa@@aA!>c9j^&*tOf::fOt*&^j9'Gc32+>74.#"32>%QnAF~hgxA,=' 0&7+Li?BmM*'IiAHoL(L6ic^zFDzg>oji8;4,.CmL)+Lj?DkJ&/Nfy';K$PX@SCSD@[SDY((($+74>32#".4>32#".!..""..!!..""..!n."".-""- ."".-""-y2D?K$PX@SCS D@[S DY@ /-%#$+74>32'&547>7#".4>32#".,/0G-    *!..""..!{)'3-a_Z&   %0:!!-."".-""-W(+?--  !@YMQE+!!!![[>ևW(+75467%>7.'%.=++?  oJ"(<9@6BhfSCSD(&#-$+>32#'54>54.#"#"'4>32#"."KYg3232>54.#"3267632#"$&54>32%2>7&#"Nb :N54&#%!2>54&#!Ʉ{;!CeDCx6SwM$RxO&4`W5bTB[l; &E_9o$@[6~vZ .D@ABhfSCSD)'..+2#".546$32#".#"32>76 LXbi Y? (6Jb@sMMi@fWK&( SfrkkbTY  O҂ґL 1" @S CS D!(!$+#!!24.#!!2>ffHsUsH̡ggАLL! .@+YQ CQ D +!!!!!!P-$! (@%YQ C D +!!!#!PL Z@4K@H! Bh[SCSD,*%# 44+%2>7#"&=!#"$&546$32#"'.#"-:aVL&6uYigU}j.7>YySyĊJM <n':'kj/C*X (%OтՔN8 @Y C D+!#!#3!38t@ C D+!#3<QKPXBBYKPX@ CSD@h CSDY!&$+#"'>7>3232>53;smai<2BgG%xF9(TZ:"&@# B[ C D)(% +3267>;#".'.+#3I&-) %*: !X% $Y  9  p@ CR D+%!!3pl£#%@"Bh C D!6)+>7>;#467+"'#32o  --  53q g0--2 8@ C D!+2.53#"&'#3>bd 1g70\'@SCSD((($+#"$&546$324.#"32>ffffHtsHHstH̡kk  llґNN҄ёMM*@'[S C D !+#!2#'32>54&+ɄAFȁSV,?tedxC,OnB\$0s BK PX@kSCSDKPX@SCSCD@kSCSDYY(((%&+#"&'#"$&546$324.#"32>)NpFp$89{CfffHtsHHstHe/sk  llґNN҄ёMM#2@/B[S C D#!,!+#!2#"'.#'32>54&+Ɓ>0[S$5((UW,V7h[LiJ())Kh?:==@:=BhfSCSD;9(&#!#"+#".#"#"&'7>3232>54.54>32 -EaEAdC";a{{a;@{rQ86QsSElK(;`{{`;;pkxJ")"#53#".53Ya3OԄԔO3a7>;#  " "P++P"g( @#B C D+< +32>7>;2>7>;#&'#"(  Q#8!O )#A  >""?4C!<gE)%@B C D("(!+ 3267>; #"&'+'va %   PY@ B C D,"+#32>7>; H G ::_#>>"-V $@!Q CQ D +!!547!52,H"Lv '@$[OQE !#+!+32pFF @kD# +32#"&'L!0 YK8 " '"#Z !@[OQE!"+46;#"&=!!Zp3F@ Bk D+!+3#"&'.'+sf z`+,+[@MQE+!5xx& @kD  +2#"&'! f \z)9}@ !/BKPX@'h[SCS D@+h[SC CSDY@+*10*9+9%##' +!#"&/#".54>754&#"#"&/>322>75zO (LT_:;gL-BecAYA/ TvUZ.2/NE?{l1,<^$9'!BeE32#"&'#"32654.?iXd632#".54>32E#6M8JrM'*LmDAT8$ 2Bn_xE?ysj?A 5dX\a3&AQKF|qNE?H%p@ BK"PX@CSCS D@!CSC CSDY@%%+!"/#".54>323%267.#"[& AlWd632#".54>"!4.#[p?^0TtHCaF/ 2!\ip7iHAzr'"B_=sl*`_/$A(;&GʃjM>gK)]@ BK2PX@SCQC D@YSC DY@ 4%+3'.=354>32+"!!p1[PD: .K6%] IbW]0Y6XA]29M]@2A*BKPX@, [[CS CSD@/h [[S CSDY@ONWUN]O]JH@>#!99 +2!#"'#".5467.54>7.54>4.'32>2>54&#"Bs/*s"9eSG? !:`zz`:Azoon7_S+3!0 KU9f*H^hl19G#HmJHrO*6S8qlkq8RB! APJyV..$% 2XFAz_9,Ja5KiC8/.**]JyU.&. N6";+0BN6K-]nn]-K6-@*BCSC D##+33>32#4&#"AgSU,ilO:ES7eV{sLAGK PX@SCC D@SCC DY@  +##".54>32X#.-##-.# >-##-/##/(Y BK PX@SCCSD@SCCSDY@%#U%+#"&'7>323265#".54>32X EmL!6 NB#.-##-.#=iN- ` IQ@>-##-/##/0@-B[CC D%(%!+3267>;#"&'.+#K.@ 2 Ws   X@C D+#X?*V) BKPX@SC D@CSC DY@**##&$! +332>32>32#4&#"#4&#"j& 8\gEVa2P}W.hc,O<#b^Bq/%hEXra7P43b\{w{<[<{zxG= LBKPX@SC D@CSC DY@ #$!+332>32#4&#"j& BkSU,ilO:%nIZ7eV{sLAH#NK PX@SCSD@SCSDY@## +2#".54>2654&#",o}CC}oo~DD~oLpK%%KpJwxIIxwJxɴ4bZZa4%@ BK PX@SCSCDKPX@SCSCD@!CSCSCDYY@%%($!+32>32#"&'"32654.j& AmWd69@PIB6ʻc[*H%KPX@ B@ BYK PX@SCSCDKPX@SCSCD@!CSCSCDYY@%%(#+##".54>32763267.#"Ų@iWd632#"&#"f 4g*D:4]}*jwlg{><=@:<BhfSCSD:8'%" #!+#".#"#"&'7>3232>54.54>32 &7L4-H3-J^c^J-2b]j<*(9Q=4N4-J_c_J-0\Vd:N(5'4&!([A:kQ0?7,>!t@ BK2PX@$jhQCTD@"jh[TDY@ !!+"&5#"&=7>;!!32>32xz)Z">1) 4.~lG9@>U+1zLBKPX@CS D@C CSDY@ $!#+32673#"/#".5,jkN:j& BjSV+zs~JB %mIY7dV@BC D, +32>7>;#ct$H##H$ . @'BC D*!,< +32>7>;2>7>;#"'.'+ M      t$C""C$p#D!!H "/0R"@BC D("(!+ 3267>; #"&'+  c  @@BCD,""++32>7>; ^  ,,}FU@QCQ D+!!5467!5!U ) '#&J #ߌ,@3@0$B[[OSG86303++4춮.54>;+";2#".54>FCCF)S{R5 MY)7!!7)YM 5R{S)?QkP@2bbd4EtT.OeV8hcb2&A3% %4@%2bch8WdP/TtE4ccbp@QD+3#把X,@5@2B[[OSG?>=<1/,)3)++546;2654.54>7.54>54&+"&=323"*R{R5 MY)7!!7)YM 5R{R*FCCF2bcc4EtT/PdW8hcb2%@4% %3A&2bch8VeO.TtE4dbb2@PkQt9@6jkO[SG +2673#".#"#4>32AI%Ef@4f_V$AI%EeA4f_VeUFCpP, '!TGCpP-!'! !&@#SCQD +4>734>32#". y "--""--"-UW\44\WU--""-.""..7@ 32&*BK PX@)jhfTCSDK PX@)jhfTCSD@)jhfTCSDYY@ ##'#+.54>?>;#".'>32+1\q?B~w BR6. !-?*4?U;& 0 " ?HJ9c4[>@@=7+Bh[SCS D%&#&'%" +46;4>32#"&'.#"!#!>3!#!5>5#4 6nnNy^EH   )3B-?`@ {929 <">0$^{G'DZ4. /#*NnDHKm-Ls "3E.!`#7?@< !B @ ?WSD42*((+467'7>327'#"&''7.732>54.#"![,h:9f+Y"![,h99e,Y"#>Q//S=$$=S//Q>#9e,Z"![,g:9f+\"![,g:.Q=$$=Q./R>##>R,S"8@5 B Z Y C D"! ,! +!32>7>;!!!!#!5!5!2h !g3TTq(#:;"6fig;gip@YQD+3#3#把rHZA@>HXN=#BhfWSDFD-+(&!#!+#".#"#"&'7>3232>54.5467.54>32>54.'1 &7L40M51OfifO1NT1>2a\j<)(:U?2O62RhnhR2V]2?0\Vd:Fm>604FOT(B6*8&9/+.7G\=Q&%bEFwW2E6D #->&-B3*,3F]@N}#&iK:kP0>73G95K/$8.&##IV{'3K PX@ S D@OSGY((($+#".54>32#".54>32 )(() g)))) ((**((**D.Jb@ BK PX@4hf[[ SCSD@4hf[[ SCSDY@ _],,*(#%(%" +>32#".54>32#".#"32>4>32#".732>54.#"  =9tbs?Ezbl9. 2L;FqO++Lj>0B0%R4_ee_44_ee_4d,RrXc-RsXb@BIDzdeyCD7A -TxKMyR+  e`44`ed`44`eYtS-dYvS.e\?T)5E@B!-Bh[WSD+*/.*5+5%##' +#"&/#".54>754&#"#"&/>322675T< .28"&A0&Xk:9&2%4yI6T:3J$Fa<4H 1  )<)"C5#%?< *1."BK PX@/h  [ [SCSD@/h  [ [SCSDY@44VTLJ4I4H)!*,,& +4>32#".732>54.#"#!2#"'.#'32>54.+D4_ee_44_ee_4d,RrXc-RsXb kj ! Pt7M/+F4e`44`ed`44`eYtS-dYvS.e|}z^ . r(:&%8$RD@MQE+!!>DuF''@WSD((($+4>32#".732>54.#"F2XwEEwX22XwEEwX26I**H66H**I6hCvW22WvCBuW33WuA*I66I**J77JdP" 7@4YYMQE  +!!#!5!!!ikkBpx%RQe-9@6+ Bh[SD(&"  --+2>;2!546?>54&#"#"&/>Z4U:M+  455370* jjT|Re=S@P9Bhh[[SD640.*)('== +2#".'763232>54.#5>54&#"#"&/>b3R; wBE*E[09T=+7 + / 'A/WG:009  C,ATe3D(-N>7T91H/ (+W<424/( 5O5U @kD #++7>3Uj!  z3@0BCS CD&$!#+32673#"/#"&'#"&5,liN:j& CWJp'Y&)nmxJB %mHD3.*W&($*7*@'hiS D+##!#".54>3۝hu??uh77]=iQVe8|@OSG($+4>32#".|)68((86)Q8((86))6 KPX@  B@  BYK PX@^TDKPX@jTD@jjTDYY@+232654.'73#"&'76 *+)<&+pZQ 9P0)J ! PE6 3$7xD_O BK$PX@jjQD@jjMRFY$+37#"/733!k  'li+X 8zUH<)@&WSD +2#".54>2654&#"~FqP,,PqFGrQ,,QrGTSSTWSS+PsGHtQ++QtHGsP+iddhhddi %%(+7'&54767&'&54?%'&54767&'&54?:   :(:   :   {{   f| &0O@L$ Bh  Z [  CS  D0.+)&% $!# +3+#5!"&/3%37#"/733!4673+>;m Rm V|k  'li,L2. M A  9;+X 8zU,\ f]-=Ge@b710+ Bhh  Z [  CS  DGEB@=<;:9853/.(&"  -- +2>;2!546?>54&#"#"&/>%37#"/733!+>;f4U:M+  455370* jj3+X 8zUv\ D}NT^x@uJ  %RB h  h  [[ \ S CS D^\YWTSGEA?;:980.)'!NN!#+3+#5!"&/32#".'763232>54.#5>54&#"#"&/>4673+>;m Rm V|B3R; wBE*E[09T=+7 + / 'A/WG:009  C,AT,L2. M A  93D(-N>7T91H/ (+W<424/( 5O5\,\ ,)=9@6BhfSCTD('#-$+#".54>?332>324>32#".KXh2/ IB@:> IBYK PX@0hfSCSC SDK PX@0hfSCSC SDKPX@0hfSCSC SD@7hf hSCSCSDYYY@GE=<861/'% KK +232654.'7.546$32#".#"32>7632#"&'76 *+)<&$Vi Y? (6Jb@sMMi@fWK& LSZQ 9P0)J ! v ukbTY  O҂ґL 1" Sap7E6 3$7!&( 7!&( 7!&( B!&( B&, &, {&, x&, 2!,@)YS CS D!%(!+3!2#!#%4.#!!!!2>2ffHt}UtH gg2АLrL8&1\&2 \&2 \&2 \&2\&2 ~X  (+  ' 7 b__d_YX`b`dY`X\!-8h@21&%BKPX@kCSCSD@jkSCSDY)*%(%$+#"&'+&546$327>;.#"4&'32>flOd:Np{fsSR dgpAKE54&+ɄAFȁSV,?tedxC,OnBvHwKPXBBYKPX@hSCSD@#hSC CSDY@CB=;%# HH+2#"&'7>3232>54.54>54.#"#4>gb/+@K@+5P]P59dOa<)(7K5,F18TbT8-CNC-8Y?DoO+E<]n332#"&'#".54>754&#"#"&/>32>32>5"!4.Rg;.MiAE\=&/!Wcj4u7Wjw;ErS-BecAYA/ Tqx!6{l1dQ9cI*=`E)X8#FjH32#".#"32>32#"&'76 *+)<&%Sf:?ysj?/#6M8JrM'*LmDAT8$ 2;aZQ 9P0)J ! y OqqNE?@ 5dX\a3& AHJ:E6 3$7J&HCJ&HvJ&HJ{&Hj&C(&v6&){&jL4H6@3:0B43@[SD65@>5H6H.,$"+.54?.'.54?7#".54>32.'2>7.#"g-e9`Q#a{xb}H>thdAu^_GsQ.4Kc>KqL'.Pi) H"><0z9 C1|nVB{p^~JVW@6mo+Q?%2WwDQV-&QH&RCH&RvH&RH&RH{&Rjd"++@([YOSG(((%+!!4>32#".4>32#".dBb!--""--!!--""--!."".-""-S."".-""-@-I!+5t@43%$ BAK PX@ jkSCSD@ jkSCSDY@ -,,5-5%%(%'+#"&'+7.54>327>;&#"2>54'=BC}oL67;CBFD~oO8D Z;IoLtO(7KsO(4OFtDvxI" JE|wJ&#[aN86d$5dZ`0z&XCz&Xvz&Xz{&Xj&\v#q@ BK PX@!CSCSCD@!CSCSCDY@##(#+3>32#"&'"32654.?iWd6!&'d ]3XeO< }"==%*"1* ?  BOB:e&Zg '/&+ G6Q)E\CS@;I BKPX@1h  [SC SCSD@8hh  [SC SCSDY@EDKJDSES%##.%#' +!32>32#"&54>7&/#".54>754&#"#"&/>322>75z*"1*  ]3Xe'5 (LT_:;gL-BecAYA/ TvUZ.2/NE?{l1,< '/&+ BOB83- ^$9'!BeE ]3XeO=A@=E>E97+)&$  << +2#"&5467.54>32#!32>3232>"!4. ]3XeB4g~FAzn[p?^0TtHCaF/ 22R'!1* '"B_BOB5]%HȁjM=sl*`_/$AgK)X@C D+#X ,#@  B CR D+%!!54?3lһ%ā"*_ V6K#@  BC D+7#54? MfCLi D8&1 &Qv\'02@  BKPX@"YS C S DK"PX@,YSCQ  C S DK,PX@6YSCQ  C Q C SDK0PX@4YSCQ  C Q C SD@2YSCQ  CQ C SDYYYY@-+#!(# +!!!!!5#".54>3254.#"32>'P-T\\ꎡT@whhxAAxhhw@$xk  ly3ӔOOӄӓNNHu0@K@ . BK PX@,h  [ S C SD@,h  [ S C SDY@$BA21GFAKBK:81@2@,*"  00+2#!32>32#"&'#".54>32>2654.#""!4.Rg;.MiA=Y@- 3!Wcj4w76du@@wf52"DhEGhE"e=`E*&Vv:&6>&V&< DV&= NFU&]vV&=XFU&]V&=XFU&]j#6@3 BYSCTD###"+#5432>7'.=37>3#"!Y<-Q?,Y.Q@- B&͹^9:\DIƿb:]Dd @Bk D' +#"/+3dw {ߦ~~ d@Bk D+ +32>?>;#{   wߦ }  } RDq D @W D +".5332>532MhA~"9++9"~Ai+Ib7!9((9!7bI+@SD($+#".54>32#.-""-.#:-""-/##/jk=KPX@WSD@[OSGY$&($+4>32#".732654&#"j 7H()I8 8I)(H7 d6/-77-/6#*D22D*)D00D),88,-88 YKPX@ B@@ B@YKPX@ SD@jSDY@ +2#"&54>732> ]3Xe+;"\*"1* BOB;6/ '/&+ YQK.PX@WS D@O[SGY@ +2673#".#"#4>32$'l/A(#=60Ho0B'#=6/-*,/O8"X0O9"^ #@ SD   #++7>3!+7>3 J !!V!  0!YBK(PX@SCS D@SC CSDY@! 6##++#!#"&'7>3265#54>3sy"BB9 H$rw K >B|@   @MQE+!!  @MQE+!!2:'(+.5467rYP7 0a0ZE"  ,16 D&  ZF(+'.547>54&'&547YO7 0`0[E"  -16 D&  ZF(+%'.547>54&'&547YO7 0`0[E"  -16 D&  :W1(+.5467.5467rYP7 YP7 0a0ZE"  ,16 D&  ,0a0ZE"  ,16 D&  Zv1(+'.547>54&'&547%'.547>54&'&547YO7 YO7 0`0[E"  -16 D&  ,0`0[E"  -16 D&  Zv1(+%'.547>54&'&547%'.547>54&'&547YO7 YO7 0`0[E"  -16 D&  ,0`0[E"  -16 D&  v3@0 BCSCD#$&"+4632632>72!#"'!v)+"LPP'(57&NE,(x&75(w0 0<` v/G@D %$ B[C SCD/.$$#$&" +4632632>72!!#.'#"'"&=!!v)+"LPP'(57&NE,(x(,EN&75(NE+)w0 0<<00<X,KPX@ SD@OSGY($+4>32#".;dLMe;;eMLd;SMe;;eMMd;;dXV';@SD((((($+74>32#".%4>32#".%4>32#".X!..""..!!..""..!!..""..!n."".-""-."".-""-."".-""-H'1EYmKPX@+[   [SC  S  DK"PX@/[   [SC C  S D@3[   [ CSC C  S DYY@~|trjh`^VT((%#&((($+#".54>324.#"32>>;+#".54>324.#"32>%#".54>324.#"32>4Wt?DsV00VsDCuU11A%%A00A%%A1  54Ws?DsV00VsDCtV01A%%A00A%%A1h4Wt?DsV00VsDCuU11A%%A00A%%A1?T[00[TV\00\VB\;;\BA[99[}  RT[00[TV\00\VB]::]BAZ99ZAT[00[TV\00\VB]::]BAZ99Z(+5:  :   (+'&54767&'&54?:   :{   D# @ C D#"+'+>;,L2. M5\ "rG[@X 5 Bh  h [   [SC S  DGF@?>=9720"###%$+3>32#".#"!#!!#!32>32#".'#53&45467#"_lF=%>aK #j6R<+   KFЏtW~ˏLdXD &.&7(8 % FfqOӃf)@I)&C@@BhS  CS  D&&!4) +>7>;#7+"'#32'###5  jn  nj ~U/ mKMHP iiV~71@.1BSCS D76***+!>54.#"!"&=!5.54>32!#DQc7E{dd{E7bQ$`l;cc;m`$Ag]km88mk]gAJ#d`e֚VVրe`d#\2*>C@@0Bh[SCSD,+64+>,>#'(($+>32#".54>32>54&#"#"&'2>7.#"\'INV3Zh9IݔVh:Lph0|*G8*  xBw`G &>W:TX- mWAfF%b @ B CR D+3!%!.'`SM   g:"";> $@!Q CD +##!##5 WWT&@#BQ CQD+!!!!5467 .5Te=Q u ;4;A  \@MQE+!!\."@ Bj[ D,# +#"&=!2>7>;#)O  s֕!)9e D"8GP: ';OL@IK-B[  O  SG=<)(GE32>32%2>7.#"!2>54.#"8[MAAL\7>qU22Uq>7\LAAM[8>pV22VpO$>7227>$$?00?$?//?$$>8228>";L**L;"0Y|LL|X1";L**L;"1X|LL|Y05E''E4/H00H//H00H/4E''E5\#(@%BSCSD6''"+>32#"#"&'7>32>7v&E do AcK#J   :W=%CV  mvf_- L ;]B~7@0!/"BK PX@+[[ O[ SGKPX@$[[ WSD@+[[ O[ SGYY@42+)&$77  +2>7#".#"'>322>7#".#"'>326." #p=4ge_-8." #qB5hd_-6." #p=4ge_-8." #qB5hd_Z r/.!(!  m31!)!  q0.!)! m31!(!~kK PX@)^_ ZMQE@'jk ZMQEY@  +!733!!!#7!5!7!rr_2wwK_VȇP!@@MQE+!!G.32yz   z{ P!@ @MQE+5467%67.'%.=!5!)81GJz   z"@ BMQE+3 #>7 &'|z|  54&&EF+#&@CD+3#!a@ BK2PX@SCQC D@YSC DY@!!U%+3'.=354>32#"&#"!#!p:ts&O dT] I8]p> ] 3`BK&PX@SCQC DK2PX@"CSCQC D@ YCSC DYY@A!% +3'.=354>32;#.#"!!p4hhSHd6m(] I6TpB Y*6 @SD  +2+h  >1P 2H4  @ja  +2#"&'% Ӌ  v'@OSG((($+#".54>32#".54>32)'')((((''))''))D'"@MQE+!!D"j  @ja #++7>3    x@Bja* +#"&/&'+73x     __ x@ Bja,!+#'32>?>;     ^^J (@%jOSG   +"&53326533sNVVNssr;==;i|@OSG($+#".54>32"-,!!,-",!!,,"",v-!@[OSG$&($+4>32#".732654&#"v3D&'E55E'&D3Y6/-77-/6{'B//B'&@..@&+99+-88V1@.O[SG +2673#".#"#4>32#%b*>(#@;4"%d+?'#@:4)%+H5+$+I4N  +@(OSG   #++7>3!+7>3V&!`(   | @SD  +2+   >9 !;ZBGC_<ʓ^pӡD- V DC'-6j$H~RXXJ `d^dX<hl(lln`"lVP ZZlZfx<R0<\<\$:PVXXZf&\^J^HJ2XjXXHP^H&d>,XzFX,XXXt4,Xrf<D\d<DfFdRTfXz:*"|fxHffD,P P P P P P BZZffff*2<\<\<\<\<\~<\\\\\\\`\JJJJJRLXXHXHXHXHXHdX@XzXzXzXzPP \ZZJJ>,6X\HH:d>$:d>VFVFVFjffff ffjfff^0Xj:ZZ:ZZvvX HxxfD"@V\pX>XTz.X: tffffDffffffvffNfl#`  JNJ#$J&*2490:0<?0DFGHRTmNoNyN}NJJJJJJJJNNNNNJ J  N  J # $J & * 2 4 90 :0 < ?0 D F G H R T mN oN yN }N J J J J J J J  J  N N   N N N J # & * 2 4 F G H R T J  N  J # $J & * 2 4 90 :0 < ?0 D F G H R T mN oN yN }N J J J J J J J  J  N N   N N N J  x#&*247L9L:#>&>*>2>4>F>G>H>R>T>>>>>>>>>>>>>>>>>>>>>>>>?J? J? J??"?#?&?*?-2?2?4?7|?8?9x?:?<\??x?Y?\?lJ?m?o?rJ?tH?uH?y?{H?|J?}????????????\???\???J?J?J?J????JDD D DYDZD\DlDrDtDuD{D|DDDDDEE E E E9E:E?E@EYE[E\E`ElErE|EEEEEHH H H H9H:H?H@HYH[H\H`HlHrH|HHHHHIDI DI DI~I~IlDIrDItdIudI{dI|DIDIDI~IDIDI~IDKK K KYKZK\KlKrKtKuK{K|KKKKKNFNGNHNRNTNNNNNNNNNNNNNNNPP P PYPZP\PlPrPtPuP{P|PPPPPQQ Q QYQZQ\QlQrQtQuQ{Q|QQQQQRR R R R9R:R?R@RYR[R\R`RlRrR|RRRRRSS S S S9S:S?S@SYS[S\S`SlSrS|SSSSSU|U|UDUUUUUUUUU|U|Y Y|Y|YY$YFYGYHYRYTYYYYYYYYYYYYYYYYYYYYYYYY|Y|YZZZZ[F[G[H[R[T[[[[[[[[[[[[[[[\ \|\|\\$\F\G\H\R\T\\\\\\\\\\\\\\\\\\\\\\\\|\|\^#^&^*^2^4^F^G^H^R^T^^^^^^^^^^^^^^^^^^^^^^^^l JllNllJl#l$Jl&l*l2l4l90l:0l<l?0lDlFlGlHlRlTlmNloNlyNl}NlJlJlJlJlJlJlJllllllllllllllllllllllllllllJllllllllNlNlllNlNlNlJmNm m Nm Nmxmxmm$m7Lm9m:m;m<`m=m?mlNmrNm|Nmmmmmmmm`mm`mmmmNmNmxmNmNmxmNmoNo o No Noxoxoo$o7Lo9o:o;o<`o=o?olNorNo|Noooooooo`oo`ooooNoNoxoNoNoxoNopp p p p pppp$p7p9p;p<p=p?p@p`plprp|pppppppppppppppppppppr JrrNrrJr#r$Jr&r*r2r4r90r:0r<r?0rDrFrGrHrRrTrmNroNryNr}NrJrJrJrJrJrJrJrrrrrrrrrrrrrrrrrrrrrrrrrrrrJrrrrrrrrNrNrrrNrNrNrJt HtHt$Ht9:t::t<(t?:tHtHtHtHtHtHtHt(tHt(tHu HuHu$Hu9:u::u<(u?:uHuHuHuHuHuHuHu(uHu(uHyNy y Ny Nyxyxyy$y7Ly9y:y;y<`y=y?ylNyrNy|Nyyyyyyyy`yy`yyyyNyNyxyNyNyxyNy{ H{H{$H{9:{::{<({?:{H{H{H{H{H{H{H{({H{({H| J||N||J|#|$J|&|*|2|4|90|:0|<|?0|D|F|G|H|R|T|mN|oN|yN|}N|J|J|J|J|J|J|J||||||||||||||||||||||||||||J||||||||N|N|||N|N|N|J}N} } N} N}x}x}}$}7L}9}:};}<`}=}?}lN}rN}|N}}}}}}}}`}}`}}}}N}N}x}N}N}x}N}J J J"#&*-2247|89x:<\?xY\lJmorJtHuHy{H|J}\\JJJJJJ J J"#&*-2247|89x:<\?xY\lJmorJtHuHy{H|J}\\JJJJJJ J J"#&*-2247|89x:<\?xY\lJmorJtHuHy{H|J}\\JJJJJJ J J"#&*-2247|89x:<\?xY\lJmorJtHuHy{H|J}\\JJJJJJ J J"#&*-2247|89x:<\?xY\lJmorJtHuHy{H|J}\\JJJJJJ J J"#&*-2247|89x:<\?xY\lJmorJtHuHy{H|J}\\JJJJJjmjojyj}jjjjjj $79;<=?@`lr| $79;<=?@`lr| $79;<=?@`lr| $79;<=?@`lr| $79;<=?@`lr| $79;<=?@`lr| $ $ $ $ \  h`h\""#$\&*-824DF`G`H`JTPQR`ST`UVXYZ[|\lm`o`rt2u2wy`{2|}`\\\\\\\````````````\`````hh```\ $79;<=?@`lr| YZ\lrtu{| YZ\lrtu{| YZ\lrtu{| YZ\lrtu{| YZ\lrtu{| YZ\lrtu{| 9:?@Y[\`lr| 9:?@Y[\`lr| 9:?@Y[\`lr| 9:?@Y[\`lr| 9:?@Y[\`lr| YZ\lrtu{| 9:?@Y[\`lr| 9:?@Y[\`lr| 9:?@Y[\`lr| 9:?@Y[\`lr| 9:?@Y[\`lr| 9:?@Y[\`lr| 9:?@Y[\`lr|J J J"#&*-2247|89x:<\?xY\lJmorJtHuHy{H|J}\\JJJJJ YZ\lrtu{|jmjojyj}jjjjjj 9:?@Y[\`lr|t t t9^:&`.d8TvlHPTn"`N*ZN  z !!"# #j##$n$$% %l%&&X&&'('l''(l))*>*J*V*b*n*z**++++,,, ,,,8,,,,,,,,------......../00000000111111112(2222223d3p44445d6"6<6p66678T8`8l8x888888889*9R9999:4::;;x;;;<<0<~<==j=>>p?~???@~@ADAABBNBhBC8CD8DDEEHE^EF8F`FFFGG4GbGGGH@HzHb"/n n* ( 0/ G V 2 2J |> X l t T  P  `> 0   0  d  8 4Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.LatoRegulartyPolandLukaszDziedzic: Lato Regular: 2013Lato RegularVersion 1.105; Western+Polish opensourceLato-RegularLato is a trademark of tyPoland Lukasz Dziedzic.tyPoland Lukasz DziedzicLukasz DziedzicLato is a sanserif typeface family designed in the Summer 2010 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in 2010, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness.http://www.typoland.com/http://www.typoland.com/designers/Lukasz_Dziedzic/Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic (http://www.typoland.com/) with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1 (http://scripts.sil.org/OFL).http://scripts.sil.org/OFLCopyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.LatoRegulartyPolandLukaszDziedzic: Lato Regular: 2013Lato-RegularVersion 1.105; Western+Polish opensourceLato is a trademark of tyPoland Lukasz Dziedzic.tyPoland Lukasz DziedzicLukasz DziedzicLato is a sanserif typeface family designed in the Summer 2010 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in 2010, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness.http://www.typoland.com/http://www.typoland.com/designers/Lukasz_Dziedzic/Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic (http://www.typoland.com/) with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1 (http://scripts.sil.org/OFL).http://scripts.sil.org/OFLtx  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#NULLuni00A0uni00ADmacronperiodcenteredAogonekaogonekEogonekeogonekNacutenacuteSacutesacuteZacutezacute Zdotaccent zdotaccentuni02C9EuroDeltauni2669undercommaaccent grave.case dieresis.case macron.case acute.casecircumflex.case caron.case breve.casedotaccent.case ring.case tilde.casehungarumlaut.case caron.saltVV, `f-, d P&ZE[X!#!X PPX!@Y 8PX!8YY Ead(PX! E 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #B *! C +0%QX`PaRYX#Y! @SX+!@Y#PXeY-,C+C`B-,#B# #Bab`*-, E EcEb`D`-, E +#%` E#a d PX!0PX @YY#PXeY%#aDD`-,EaD- ,` CJPX #BY CJRX #BY- , b c#a C` ` #B#- ,KTXDY$ e#x- ,KQXKSXDY!Y$e#x- , CUX CaB +YC%B %B %B# %PXC`%B #a *!#a #a *!C`%B%a *!Y CG CG`b EcEb`#DC>C`B-,ETX #B `a  BB` +m+"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-,+ETX #B `a  BB` +m+"Y-,+-,+-,+-,+-,+-,+- ,+-!,+-",+-#, +-$, <`-%, ` ` C#`C%a`$*!-&,%+%*-', G EcEb`#a8# UX G EcEb`#a8!Y-(,ETX'*0"Y-),+ETX'*0"Y-*, 5`-+,EcEb+EcEb+D>#8**-,, < G EcEb`Ca8--,.<-., < G EcEb`CaCc8-/,% . G#B%IG#G#a Xb!Y#B.*-0,%%G#G#aE+e.# <8-1,%% .G#G#a #BE+ `PX @QX  &YBB# C #G#G#a#F`Cb` + a C`d#CadPXCaC`Y%ba# &#Fa8#CF%CG#G#a` Cb`# +#C`+%a%b&a %`d#%`dPX!#!Y# &#Fa8Y-2, & .G#G#a#<8-3, #B F#G+#a8-4,%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%aEc# Xb!YcEb`#.# <8#!Y-5, C .G#G#a ` `fb# <8-6,# .F%FRX ,1+!# <#B#8&+C.&+-?, G#B.,*-@, G#B.,*-A,-*-B,/*-C,E# . F#a8&+-D,#BC+-E,<+-F,<+-G,<+-H,<+-I,=+-J,=+-K,=+-L,=+-M,9+-N,9+-O,9+-P,9+-Q,;+-R,;+-S,;+-T,;+-U,>+-V,>+-W,>+-X,>+-Y,:+-Z,:+-[,:+-\,:+-],2+.&+-^,2+6+-_,2+7+-`,2+8+-a,3+.&+-b,3+6+-c,3+7+-d,3+8+-e,4+.&+-f,4+6+-g,4+7+-h,4+8+-i,5+.&+-j,5+6+-k,5+7+-l,5+8+-m,+e$Px0-KKRXYc #D#pE (`f UX%aEc#b#D * **Y( ERD *D$QX@XD&QXXDYYYYDPK!Zoo6generator/template/darkfish/fonts/Lato-LightItalic.ttfnu[GPOS'HPGSUBV.TIlOS/28J|`cmapRԟJcvt &6e8fpgm zAe gaspeglyf^Oheadd6hhea1$hmtx?kTkernOQ@gloca)N4,maxp> P` nameBbdP}post:\bprepx9op 0JDFLTlatnkernkernGrTv   V 8,^$^ 0 DJJJL F !z" ##P#$4$~%x&&'()*++,J,-n../$/V///1242n2233V3344J4445567778~88:;";;<=2>,?&?@ABC8CDE.F(> [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[> [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[-#&*24DFGHRTkp> [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[0= = =I#&*247A9=:m > >GG"F#$&*-o24DFGHPQRSTUVXYZ\]kl>mopr>tPuPwy{P|>}>>G>>GG$ $79;<=?@`lr|:V V V#&*-224789: LL"$-.DFGHPQRSTUXwLLL $+  #&*24IWYZ\klmopry|}3 $#&*24789V:y<=?VYzZ\zklm$o$prt=u=y${=|}$=zz=$$$$$$ $79;<=?@`lr|/ ==$-VDFGHRT===$ $79;<=?@`lr|#&*2478kpf LLL]]"-#$&*-824D)F)G)H)JAP]Q]R)S]T)U]VFX]YQZy[b\L]ekmLoLpw]yL}L)))))))))))))]))))))]]]]QQ)))])FFeeeLLLLLLLL $q> > >GG"F#$&*-o24DFGHPQRSTUVXYZ\]kl>mopr>tPuPwy{P|>}>>G>>GGNF F F$-DFGHJPQRSTUVXlFrFt<u<w{<|FFFFF+  #&*24IWYZ\klmopry|}m4 ~ 4 4[V[~"2#$~&*-824DGFGGGHGJ_PQRGSTGUVGX]kl4mVoVpr4t2u2wyV{2|4}V~~~~~~~GGGGGGGGGGGGGGGGGGG~GGGGGGVV44[44[V[VV~" #&*24kmopy}-#&*24DFGHRTkp:V V V#&*-224789: [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[&y y yjj$7G9; [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[ ee$e9F:F<(?Feeeeeee(e(e ee$e9F:F<(?Feeeeeee(e(e&y y yjj$7G9; [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[&y y yjj$7G9; [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[> [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[0= = =I#&*247A9=:m [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[> [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[0= = =I#&*247A9=:m [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[:V V V#&*-224789:?EHIKNPQRSUYZ[\^klmoprtuy{|} 8DFLTlatncase&case,liga2liga8sups>supsD,>B      @ LO,{tu CjqvI,xxAP`KtyPLJz  &   !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ardeixpkvjsgwl|cnm}byqz`T@ ~1DS[a~    " & 0 : D !"!&"""""""+"H"`"e%&i 1ARZ`x    & 0 9 D !"!&"""""""+"H"`"d%&i{uq[H$I޸ޡޞ:ڜ`T@ ~1DS[a~    " & 0 : D !"!&"""""""+"H"`"e%&i 1ARZ`x    & 0 9 D !"!&"""""""+"H"`"d%&i{uq[H$I޸ޡޞ:ڜ/,8<@BK PX@3 `f[[ Q CQ D@4hf[[ Q CQ DY@@?>=<;:9751/+)&$$ +>32#'.<54>54.#"#"'4632#"&!!7!!374>32#"&F  >F!""'5-PS\88\SP-<""!5t ,@) Bk D   $+#"&'7!#"&'7e$  &]$  &ܚ$ܚ$Pr:>yK)PX@(  Y  C Q C D@&  Z  Y  C DY@>=<;::5320-,'%#"!#!+#"&547!+#"546?3#76;>;!323+32%!!' Ԇ)ۂ )։(+)   ,E  l%D  m$yErB[9DO@! *BK PX@2j  h f_ SC SD@1j  h fk SC SDY@LKA@#$#$ +.'7632.54>?>;#".'+4.'>ေ>  "/AU8oc6M9*,6Tl}8'0DXuKPX@+[ [SC C SD@/[ [ CSC C SDY@ US((%"&((($ +#".54>324.#"32>>;+#".54>324.#"32>7Zt>3W?#4XvA3V?$J.>$0XC'-?$0WC(XAB7Zt>3W>#4XuA3V?$J.=$0XC(.?$0WB(qgh4&ImGgi5&JmI7>;#"&/#".54>7.54>32>7>hJ)40K6=eI(>;a2A <TDM/lzGG|\6:cM106b0.J_2>si^(GrP,)Kh?  E:%,Mi>EINHG ^[ 3V>#-U|NRy\FFPd8BeD"!:P/Vize @ Bk D $+#"&'7e$  &ܚ$H  (+.54>7!2! ++<' 4UxR& S~T+OH  XPVr w  (+4.'&546?'&547>\!1! ++<' 4UxR& S~T++OH  YPVr w ;*@'40/+'&" Bja;;+7>7'7>7./7.5<?3>?'.'x    2   n+n  n,n   n,n  n+n   3 .@+jkMRF +!!#!7!7O7L8Q 8=G;G?@B ?S D"+74632'.54>7#"&?0'+/(8"'$ %/U#2;0)URL  %9J,2c*x@MQE+!!n RxN:@SD&$+74>32#"&:!#7''5M""'55@kD""++6; !&''/$Z`',@)SCSD'' +2#".54>2>54.#"\r@by\r@b.cQ5\}GcQ5]}HّjHّGj_)ʂz;_Ƀ{;)@&Bh CR D$+%!7#"/3!!F I5(HE 'iHF51<@9- BhSCQ D+)#! 11+2>3!2!7>7>54.#"#"/>Kc9;eK G#hq !K}Z2-Mf9Du_F.\~*S}R[D8!5! C{|NCcA 'Ig?Zb4q<HU@RD Bhh[SCSDB@:80/.-%#HH +2#".'763232>54.#7>54.#"#"/>K`73XwCEgF#Qhaf< ) 2OpNag6$Vm ak8,Kd9Dv`F.[~)OvLP~^? 7Oe:`xD.\Y GhF"Ci@7aG)B2X|L@_?'Hg@Zb4>^+@( B\ C D!#+!+#!"&/367!Z1T2g;Tk 5b2 i - 'g8-@@=+*Bh[Q CSD(#&(""+#!632#".'763232>54.#"'!2kgg3[m:hXI  -HgF[yF(TXn8{_$6aP}NJJ#-'%=riBmN,%r32@/B[ CSD0.&$ +2#".54>7>;>32>54.#"Tb6QoYf7:Z> Q&>B*PsJ^p=,QtG_o=M5`RlJ7h\:qwH *K#?G-DtU0=lWFrP+Do$@!BQ C D$'++>7!"&57 H. #   >f&%;OD@A B[SCSD=<'&GE7.54>32'2>54.#"2>54.#"^m<6`MmpBxfW_1)MpH6]E'2XwE2^H+Z22@/B[SC D/-%# +".54>32+>74.#"32>MP^3OiUc5:V7H T >BV+NnBVl=)MnD]i8Z3\OfI8fVDrosEI&L)BHCqQ-9gVClK(Ai:Z;K#PX@SCSD@[SDY&&&$+74>32#"&4>32#"&:!#7''5f!#7''5M""'55D""'55<e)K@ B ?K#PX@SCS D@[S DY@ (& "+74632'.54>7#"&4>32#"&<0'+/(8"'$ %/o!#7''5U#2;0)URL  %9J,2<""'55 5(+%(BA     c!@YMQE+!!!!; /:+GG 5(+ 767>7&'&5<>7L%(A    ~'95@2BhfSCSD(&#,$+>32#7>54.#"#"'4>32#"&EQ\4=gK*1LYQ< @9NZL2 9M,>\@( "!""'5 3'&Fa;SvXA<>(,E>?PhH/K5#*# g""!5a2Wlf@c ^ ?Bh[  [  [OSGYXb`XlYlOMCA=;86,*"  WW +%"&5<7#".54>3232>54.#"3267632#".54>32%2>7.#"IG?L-B*!>ZqN1T!';sZ7Lg\a7Vz_ o^JP[ǡq=I҉ՙTD?lT7%AXck4!9*X $@!BZ C D# +!#"&'!+3!.'XLeLb>E   b z*5*=@: B[S CS D*(" !+3!2# !2654.#%!2>54&#!yfb/,QtICsJD)OsJa\,*OrHD|eIybp<:]B$H:_zAw~/D@A BhfSCSD'%" //+%2>32#".546$32#".#"ItZA. #.ixPzŋKp ItaQ&  )N}`aBvE%+%*/K5X⊹3y,B*( ,5,h|NjJ-@S CS D!(!&+#!!24.#!!2>-1[g$}ʍLg?uhxޢZ/}ڵb3Uދy†Hc? (@%YQ CQ D+!!!!!!4WG7 I 5PR? "@YQ C D+!!!#!4WJO Pd5Su9G@D$ Bh[SCSD1/(& 99+%2>7#"504>7!#".546$32#"'.#"CobZ-0k?5o}R͐MnM~hV&  '7Kb?]BzA*  %:'Y㊻3w,@)'!h|njK! @Z C D+!#!#3!3sdSSddR(RdYk@ C D+!#3 dd'@$Bh CSD#%$+#"&'7>3232>73}HnW6Y+  #1#;lW= xduq76%Wi &@# B\ C D'(% +3267>;#"&'.+#3^M"(PQ~P * TTcdL X f  UX@ CR D+7!!3h 6cUU<!'@$Bh C D!6(+67>;#>7+"'#32- ~EW nWD   y #F!@B C D!+2>73#"'#3b W. QW1 0 y-Gq'@SCSD((($+#".546$324.#"32>qm|ȍLn}ɍLg?vgޣ\@vgޢ[0xY≺3xY{ŋKh{ŊKg? /@,[S C D   !+#!2# 32>54&#GFcTJvT^k:;lHSq5aU#N ||ȍLn}ɍLg?vgޣ\@vgޢ[0⼓1{ C2Y≺3xY{ŋKh{ŊKg3!7@4 B[S C D! *!+#!2#"'.# 32>54&#POcP54.54>32  ";]FLwS,2QgmgQ2B{mS:((0GgKQsDKH @Q C D+!#!7 8c6 T3T#@  CSD +%2>73#".5473o]uL kdl]sgo:kdl-WFH~clu˖VG|e,-l(Th; @B C D, +32>7>;#O&   GN:Y c00 y~( @#B C D+; +32>7>;2>7>;#.'#N MY Yh)) h)) y  /@ B C D)"'!+ 32676; #"&'+Y -cY   b  4r p @ B C D,"+#32>7>;gIcIX+ SGH? d!  ,$@!Q CQ D+!!7>7!728 A  !  R! RDD'@$[OQE!#+!+32D& ̼ #   qH@kD" +32#"&'q'' %$+ '@$ B[OQE!#+!!7>;#"5(˻ # v @ Bk D+!+3#"&'&'+\;UC   F L1@MQE+!7 +AA~@kD+2#"/s5 <s+^@ BK%PX@SCS D@SC CSDY@ #!++*' +!#"&5#".54>322>7&#".!&[gr=?^? ,QpR32#"&'#"32>54&f]a'`ju32#".#"32>325_[^5VT*!>XnI1OB6 1N;Tk=AbC5TA1& ;L,;jVOvV1#2! % ZlEvV0")" @.p@ "BK%PX@CSCS D@!CSC CSDY@&$.. +!"&5#".54>323%2>7.#"!'alv=AbB" ;UlIQ,I\I9rk]$#+E?mYE/f =Q_42\QLb9GGKQ@?tc N@3Xt@FF,=7@42BhSCSD.--=.=*&%,+32>32#".54>32%">54.F8`Ќ5UC3( 1]_f:SX.;WpOIe?PcCO,,G%)JB;1')$($ 4K07eZKzZ4)=GgDqQ%)0361(B%^BK!PX@kSCQD@kYSDY@%%!$%$ ++'&546737>32#"&#"!2j*#~ :Wn?8  (-Q?-  ~w ~UV+ 0 AhK{F>Td@<& CBBKPX@+ [[CSCSD@.h [[SCSDY@VU^\UdVdQOGD7642*( +#".54>32.5467#".54>32!4&'.#"32>2>54&#"(/(#*#@tdO_4Kb"D#")[69bG(1]W3Z# l 1X)ca1'Hf>N[2@eF$n]@dE$l7ZKA>@$3016@'?uZ6 =X8HoL(4 #H3$GgDEh?  L1F%?T.+C-*FZ 6Wo8hi3Tm9jnf,@)BCSC D%%+33>32#654&#"f^\(akp9po ^KMS6pi^$AKuQ*2]|.)fj7gZx&@#SCC D +##".54>32Ny]yW !m(4@1 BSCCSD%#!%%+#"&'7>323267#".54>32J(?W5)JR 4XA% XQbW !c0@-B\CC D%(%!+3267>;#"&'.+#rm% R9   lP $=] { _   u@C D+33u]Q^5Z@  BK)PX@SC D@CSC DY@55%&($! +332>32>32#>54&#"#654&#"^x+#NqdU']gl5k^ ]K>M1eaW#C]K :JrI?$ꛫ~v"'PwO'} 6_|7Z]-Z\|E6TWо^!P@ BK)PX@SC D@CSC DY@ !!%&!+332>32#654&#"^x+")cnt;op ^KMS8rk^$=$O}W- 2[|.)ej9i]G%,@)SCSD%% +%2>54&#"".54>32Wf7~:fVE/wP]3HlP]3I>[g)JexFK8j`yߪe9i^yޫf2-m@ !BK)PX@SCSCD@!CSCSCDY@%#--*&!+32>32#"&'"32>54&2+# 'amv=AbB" ;UlHQ+;9sj^$#,E?mYE/fF$Q_42[PMb9HF?tdO@3XuA<s.6@3#BSCSCD&$..*) +#"&547#".54>322>?&#"6O&Yeo32&#"^x+#Dc)+.(k=<$أY!<=@:<BhfSCSD:8'%" #!+#".#"#"&'7>3232>54.54>32 2J73[C'&?OTO?&3^Ra/ 5R>;aE&&>PSP>&2Z|JT|0i"9K*)8)%4K5@x]8C6" ' 'DY2,<+#2H4:kS144l@+g@ &BK!PX@#jhQCSD@!jh\SDY@ %#(&&+74>7#"5?>;!!32>32#"&DB ./ E=0!3&(r9R]$9,5) d G)4!A:**3Zr"P@ BK%PX@CT D@C CTDY@ ""'!%+32>73#"&5#"&54>7!KMS7pj^$@^x,)cmt:oo /(fk8i\O|U- 3ZS@BC D+ +3267>;#SI  GN ,*0 Vx) @#BC D(!+: +32>76;2>7>;#"'&5+VC V$ F BVD B))** (V@BC D("(!+3267>; #"&'+sP    TP   Pr q 0  Q V@ BCD,"!++32>7>;CJ   I   <@QCQ D+!!7>7!7!6a/ ^  K& MKGFD7@4"5B[[OSG<:303)+4𑯎&54>;+";20#".54>D9J\+NoE3:P1 '?.*")"'8#38U:#*#9I;tw<-TF3 )5 =vw{A)B0  %BY4D{ut@QD+3#KKD7@45"B[[OSG<:303)+3"+7>;2>54&54>7.54>54.+"&504>732D9J\+NoE3:P1 '>/*")"'9"37V:#*#9I;tw<-TF3 (6 =vw{A(C0  %BY4D{utP9@6jk[OSG +2>53#".#"#4>32%=*N 734632#"&D ) C 5'#7''5&-PS\88\SP-'7#'55/:K@H%BjhfkSCSD##'# +.54>?>;#".'>32+Vb4Lˀ# #)V.  4N8KlI* J]l:$ #)LmEir= @o`לX ;- "' 1% Q]7lJi=C@@+ Bh[SCS D%&%##(" +#!>3!#!7>7#7>;>32#"'.#"!a%'#/)5$=/*$ LzfPuQ4(  &;XAN`= $ ,F9/'@ #4I5W% )]uC%?V0 <.4_O$D#79@6! B @ ?WSD42*((+467'7>327'#"&''7.732>54.#"(#2-n?>n-1%))#1-n?>m,1$)H+Ib89cJ++Jc98bI+>m-2%*)$2-n?>m-2$)($2-m?8bI++Ib88cJ++Jc!8@5 B Z Y C D! +! +!32>7>;!!!!#!7!7![M   N[o/]/nhd## 9v88v@YQD+3#3#KKKKX}bEYA@>EWM:#BhfWSDCA,*'%!#!+#".#"#"&'763232>54.5467.54>32>54.'K  1I76[B%(BUXUB(^](22]Ta0  4P>>bD$ImmIdq*42Z}LS{0!8IPR$NC2CJL#`M #:N*)>3,-3AR7^&"U;Dy\5B6" % 'CY2=S@:GaGU)!V>;lR145&<2+(+&kE(?3*&&+gvqm%3K'PX@ S D@OSGY&(($+#".54>32#".54632 V 0"   "1 k/Ka@ BKPX@4hf[[ SCSDKPX@4hf[[ SCSD@4hf[[ SCSDYY@ ^\*,*(#&(%" +>32#".54>32#".#"32>4>32#".732>54.#"Y";t`s@Cwc4WJA !;[DSa55_Ld0:L@I!Bh[ WSD21651:2:%#00 +"&=#".54>7>454#"#"&/>32'26? 4cB2&)[go'8)   1i?*>)  =[+9G D.11!*H7! w/-1A$ 4Ya*5)KB.)%%(+77    =     z   { z   T=K PX@_MQE@kMQEY+!#!<.O$'c*x@MQE+!!n RxNq1GP<BKPX@/h  [ [SCSDKPX@/h  [ [SCSD@/h  [ [SCSDYY@22PNJH2G2F)!**,& +4>32#".732>54.#"#32#"'.#'32654&+q4^dd^44^cc^432#".732>54.#"0Qm>?nQ//Qn?>mQ0E$>U00T=$$=T00U>$n>mQ..Qm>>lQ//Ql>0T>$$>T00T?$$?T<P8 <@9jhZMQE  +!!#!7!!!2 O1L1S2VjGlGGV/g@ - BK!PX@h[SD@!h[OQEY@+)%# //+2>3!2!767%>54.#"#"/>(E33C%(' "=,#/9Z $V,?*-LD?!;>@$-B= `e|V>@:BKPX@,hh[[SD@1hh[[OSGY@8631+*)( >> +2#".'763232>54.#7>54.#"#"/>(D2UE@A+H^3!3C$  ('0;-!2RH+B;0I2T@kD"++7>3T7 $7@4#BCS CD$$&(!&+32673#"50>7#"&'#"&5RcjXH][z3K]Xn(.cmybX ;3X[JD*R#yB4*@'hiS D+##!#".54>34 UVm\h8EnR  y-SwKVi;@OSG($+4>32#".$&&$P&&%%TV@  BK PX@^jTD@jjTDY@+232654.'73#"&'764#3:(8"8:'JN2E(&D  2* a73!5% lQN BKPX@jjQD@jjMRFY$+37#"/733!C 9R%h5;#)@&WSD## +2#".54>2>54&#"7U;+OpE8V;+Oq7T8RR:U8R$C]9O[2$B]9O\2*MlBYk+NlAYj%#(+7'&54767&'&54?'&54767&'&54?     ' '   ' '  `(.Q@N" Bh  h   Z \  C D.-('&%$#%"#!" +%3+#7!"5'3+6;37#"/733!>7!n=A &$(C  9R'"U d#k%w h5t |H9Jb@_D=7Bhh   Z [  CT D JIHGFEB@;:52/- 9 9"" +%+6;2>3!2!7>7%>54.#"#*/>%37#"/733!w &$(y(E33C%(' "=,#/>X C  9R d#K,?*-LD?! ;>@$-F9`e %w h5rY_y@vU ! . B  h h  h [  [\ S C D_^SPMKEDCB:820*(YY"#!#+%3+#7!"5'3+6;%2#".'763232>54.#7>54.#"#*/>>7! n=A &$((D2UE@A+H^3!3C$ -%0;-!2RH+E80I2 |;(:5@2BhfSCSD('#,$+#".54>?332>324>32#"&;DP\4;gL+1KZP; >6MXK1!8K)=]B'!""'53'%Db>RtS=68%+?99KeG0L5$*$P""!5X&$ @X&$ HX&$ @X&$@X&$ @X&$@:@7BYYQ CS D# +!!!!!!+!!6 W XMwz  5PRb z5+Lh@e9? J Bhf hSCSC S  DHF>=750.&$!LL +232654.'7.546$32#".#"32>32#"&'76#3:(8"/rFp ItaQ&  )N}`aBvbItZA. #-dsLJN2E(&D  2* r^܅3y,B*( ,5,h|NjJ%+%*-I5L73!5% ?&( G?&( G?&( G?&( G&, &, &, &, E`!,@)YS CS D!%(!+3!2#!#%4.#!!!!2>MR}ɍLl$T?ugHsJxݡZUމry†H>c!&1q&2 q&2 q&2 q&2q&2 )C  (+  ' 7 )cF6Z,9C 3u3wp4pO!-9b@ 21&%BKPX@kCSCSD@jkSCSDY**%(%$+#"&'+7.546$327>;.#"%4&'32>qmhC")JNnmEz 4DHw:6%:`ޣ\"409Zޢ[0x>9Q卺3xE? QvE<@h(oE67g&8 &8 &8 &8 &< &Y,@)\[ C D"& +32+#3 32>54&#Ju#cd-T^k:ilHT54.54>54.#"+'&573>InJ%4MZM4.EQE.6_M]~0  3L::^B$/HRH/5O]O54T=A{cE p*#W|-I\.FdL<:A+)3'&7TBL\3C6! % (E]58F0#-B58RC=GZ?D9&Bv^zv (_K<s&DCT<&Dv-<s&D<h&D<m&Dj<s&D22jGWd@?E!BK)PX@5hh  [ S C SD@?hh  [ S CSC SDY@&YX^]XdYdSQIHCA=;860/'% GG+232>32#"&'#".54>?>54&#"#"/>32>32>7">54&Z7]D&>y5UD3( 0\`g:t[jo08]C%F \[BaF. Qcrt 9=0B'=oY< GtY; {4b ;Q0:hN0))$($ 3K1MjA8W32#".#"32>32#"&'76#3:(8"1OtM&!>XnI1OB6 1N;Tk=AbC5TA1& 2XVV/ JN2E(&D  2* u?iSOvV1#2! % ZlEvV0")" 7I,P73!5% FF&HCFF&HvFF&HFQm&Hja`&Cx'&vB%&IDm&jIy7I5@20B76 @[SD98A?8I9I,*" +&54?.'&54?7#".54>324654&'267.#"3vD QC +H4@~L^5Ayi1`TE\UI! +GeDZ`2*Hc. y#0 =3 o(f~Yn9h[mU9X=K,3dO1H|^M{V.^j&Q++G&RC++G&Rv++G&R++Gj&R++Go&Rj++3^#+@([YOSG&&&%+!!4>32#"&4>32#"&U%$.&$,X%$.%#-G{&1#%/Y&1#%/  *5u@ 43$#BKPX@!kCSCSD@!jkSCSDY@,++5,5'%  +"'+7.54>327>;&#"2>54&'YF !&+-HlDq-= 2u),I7GnWh9Wg9G K`5[yߪe(&S5XyޫfWGYAZkBn*GBr&XC++r&Xv++r&X++ro&Xj++V&\v++;0?@<"BCSCSCD(&00*%+3>32#"&'#"32>54&;]b'`ktC#?mYF/gN\32[PMb9HGE@ud'6"3XuAVo&\j++'0L@I-BAhZ C CSD)($"''+2#"&54>7.'!+332>!.'  Q+BK*6eLbg7.3*$E  !B:">6. b y $0<")0 +,<s4FK%PX@&;B@&;BYK%PX@*hSC SCSD@.hSC C SCSDY@65><5F6F1/('$"44 +2#"&54>7.5#".54>32#32>2>7&#",  Q+BK-8!&[gr=?^? ,QpR7!!!!!!#32>X  Q+BK*6 WG7 I p3+3*$!B:">6.RPR $0<")0 FFL]e@bR9@?Bh h SCSCSDNMM]N]IG>=750.LL +2#"&54>7"#".54>3232>32732>">54.C  Q+BK$/ SX.;WpOIe?8`Ќ5UC3( /XZ_6)-3+3*$PcCO,,G!B:93-7eZKzZ4)=G)JB;1')$($ 1H0 $0<")0 DqQ%)0361(xN@C D+#Ny]y0!@ B CR D+%!!7>?3g ~Dh 6H  [c= UMf@ ^S8@BC D+46?37#S L]H _\Z TvW2 VV!&1 ^&Qv++ 46@  BKPX@*YSCQ  C S DKPX@4YSCQ  CS C S DK#PX@*YSCQ  C S DK%PX@4YSCQ  CS C S D@2YSCQ  CQ C SDYYYY@1/'% (% +!!!!!#".54>324.#"32> ZG2 H '+qVo}CeWrQ,]7g]w̕U8h\x̔TRPR>N{U-Wއ6z5aVgx‰Kkx‰Ij68N]S@PT6$Bh S C SDPO:9O]P]FD9N:N42*(" 88 +232>32#"&'#".54>32>2>54.#"">54.=aD#8^ƃy5UD3( 0\`g:yUi~GOtK$Mix:8GrW>(:W;Zh88Z~H{_? {-0J 9O0%F@80'  $($ 3K1EnL):aEZuvI2Vs?CoO+Tۈ6fP0q:k_:EN'6)'&6 !&Vv++'&6 !&V++&< &,&= F <&]v++,&=F <&]++,&=F <&]++U%SKPX@ YSCSDKPX@ YSCSDKPX@ YSCSDKPX@ YSCSDKPX@ YSCSDKPX@ YSCSDKPX@ YSCSD@ YSCSDYYYYYYY@%%"" +#763>7'&546737>3#"!VwW%3eWE//"5dWE1f b\+/FqS  1 FqREoR @Bk D' +#"/+73R= { AS r @Bk D' +32?6;#A { ?S rq$qa @W D+".547332>73e5K.C 3&,?+C#=Y5H*4%3B&2ZD'2@SD($+#".54>32    F!!s=K'PX@WSD@[OSGY$&($+4>32#".732654&#"/?##?//?##?/:@32@@23@$<++<$$;,,;$2@@22@@7\ +@(B@jSD+2#"&54>732>F  Q+BK1>-3+3*$!B:%C:/ $0<")0 |nhQKPX@WS D@[OSGY@ +2673#".#"#>32(.9(6 1-+&0:)5 2,*7/$>.!(!:-$?-!'! #@ SD   #++7>3!+7>3 ) =-  Y\BK1PX@SCS D@SC CSDY@!$## ++#!#"&'7632327#7>3Yq]qVVsb0  V$d;ns & ! ld@MQE+!!+dEBd@MQE+!! VdE#(+&5467\H):#7;XB 1v?/*\(+'&5467>54&'&547E\H*8 7;XA 1v?, (+7'&5467>54&'&547\H*8 7;XA 1v?,#)(+&5467&5467\H):\H):#7;XB 1v?/*7;XB 1v?/*e+(+'&5467>54&'&547%'&5467>54&'&547T\H*8 8\H*8 7;XA 1v?,7;XA 1v?,+(+7'&5467>54&'&547%'&5467>54&'&547|\H*8 8\H*8 7;XA 1v?,7;XA 1v?,"YKPX@#CSCSCD@OCSCDY@ $!#"+>3>32>72! #"'!FK/  GLF=O  h=&  f6* BKPX@6   `   [CSCSC  D@1   `O   [CSC  DY@661.,+)'$##!##+%!7>3>32>72!!#.'#"'"&5467XFK/  GLFZ_FK,  G&OOM$ & +'  91|@OSG($+4>32#".9.Pi<=lP..Pl=32#"&%4>32#"&%4>32#"&:!#7''5!""'5!#7''5M""'55'""!5'""'55}'0DXlKPX@/[   [SC C  S D@3[   [ CSC C  S DY@}{sqig_]US((%"&((($+#".54>324.#"32>>;+#".54>324.#"32>%#".54>324.#"32>7Zt>3W?#4XvA3V?$J.>$0XC'-?$0WC(XAB7Zt>3W>#4XuA3V?$J.=$0XC(.?$0WB(6Zt?3W>#4XuA3V?$J.=$0WC'->$0WC'qgh4&ImGgi5&JmI32#".#"!#!!#!32>32#".5#73>7#Lqr@jWI %,@W:_`e 4aY>cM:)  )^l|Fnu<^ғN,A*$$@}u *X0 zC%+% !.K5Qه9/Y*H&9@6BhiS  D&&!4) +>7>;#7+"'#32'###7 6E<6  754.#"!"504>7!7.54>32!,dyDCv]p˛[0Y|L+3N]4lrÍPKghYyjn7I׎VhF Rw\YFv}͛h3W/AC@@5"Bh[SCSD10;90A1A#)**$+>32#".54>32>54&#"#"'2>7.#"%BBD&EjH& kԂClM)&EawK1WG4ol-G6% NKv_!7V?fr=t=# 5d^AI,SvKRtT/7T:NV&Fx4dN0``yi @ B CR D+)3!.'ijYj%&w $@!Q CD +##!##7w __ PiiP*@' BQ CQD+!!!767 &5467 IR RR$2- {@MQE+!!< GES"@Bj[ D+%!+!##"&5467!267>;RM9  7 )#( L';OL@IK-B[  O  SG=<)(GE32>32%2>7.#"!2>54.#"3O?3"HPX30T>$3Un<3O?3"GPX31U?$2Up(IDA -4@(-P=$-<m0Q;"-<$(ICA!,5?'BV..VB'$C`32#"&#"#"&'7>3232>7EZl;$4  `"Kas@;  6[J7>WU+ , dZ) ' GrQ7d@a!0"/B[[[ O SG42+)&$77  +2>7#".#"'>322>7#".#"'>3243-% #i83a]\.3,% #h<4a][2-& #h84a]\/3,$ $h<5a]Z( 8+.$,$ 6-/$,$ 8*/$,$ 6-0%+% pkK PX@)^_ ZMQE@'jk ZMQEY@  +!3!!!!#!7!7!F͇ FEZ>c GGGgPO@@MQE+!!&)$@A v>    xIuPQ@ @MQE+%!7!7>767.'&5<>7c AG&)$PI>    f"@ BMQE+3 # >7 .'BnBL  M  @@S ~@ja+3v 0@T%k@ BK!PX@"kSCQC D@ k[SC DY@ !&%$ +!#!+'&5737>32#"&#"8w^nFl*"~ DlX%$  ,"<}v *U\e6. @$@ BK!PX@$kSC QC DK%PX@"k [SC DK)PX@&k [CSC D@-hk [CSC DYYY@$$!!%$ ++'&5737>32;#.#"!3l*"~ BjYE94]/h0EqU7 ~v *BXm> nL /X~NBFS-K1PX@ jD@ jaY@ +#n;N[{ @ja  +2#"&/ I   6 @OSG$$$"+#"&54632#"&546324/../O.--.,, -- ,, --6p@MQE+!! p:, @ja #++7>3  I @Bja+ +#"&/.'+73GGW@Bja+ +326?>;#GGW(@%jOSG +"&547332673gc>DNXU? {XT9AQHcr@8@OSG($+#".54>32  1!@[OSG$&($+4>32#".732654&#"-<"">-->""<-5?32@@23?^";**;"#:**:#2@@22@@1@.[OSG +2673#".#"#>32&/4&4 3/-&/7'4 4.-O7+"<, & 9*"<, %  +@(OSG   #++7>3!+7>3 -Z3 @kD  +2+ $U !;XB -M_< ʓ^pӡ  V /TPr}M((?dc:ZFq>gf:<++av?`p&BnF'5ETS,(Dq(<f]H@F8Bqfxmxcu^^G2<^!lrSSVVVF (GX(PTXXvMkk2dcMqr<y2????&&&&EnOEEEESF;<<<<<<2]HFFFFaxBII^GGGGG rrrrV;V< ]H?Fx02Sn^6'!'!S,F ,F ,F or27|<nn ggg,,f9`: }EE )!l(+WTbELe+g+u@@S{,@gP`  [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[ [ j y j [ $[ 9> :A </ ?> D F G H R T my oy yy }y [ [ [ [ [ [ [ / [ / y y j j y j y y [ # & * 2 4 D F G H R T k p [ j y j [ $[ 9> :A </ ?> D F G H R T my oy yy }y [ [ [ [ [ [ [ / [ / y y j j y j y y [= = =I#&*247A9=:m  > >GG"F#$&*-o24DFGHPQRSTUVXYZ\]kl>mopr>tPuPwy{P|>}>>G>>GG## # # # ##$#7#9#;#<#=#?#@#`#l#r#|##################$V$ V$ V$$#$&$*$-2$2$4$7$8$9$:$9 9 >9 >9G99G9999"F9#9$9&9*9-o92949D9F9G9H9P9Q9R9S9T9U9V9X9Y9Z9\9]9k9l>9m9o9p9r>9tP9uP9w9y9{P9|>9}99999999999999999999999999999999999999999999999999999999>9>9G9>9>9G99G999:F: : F: F::::::$:-:D:F:G:H:J:P:Q:R:S:T:U:V:X:lF:rF:t<:u<:w:{<:|F::::::::::::::::::::::::::::::::::::::::F:F::F:F:::;; ; ;;#;&;*;2;4;I;W;Y;Z;\;k;l;m;o;p;r;y;|;};;;;;;;;;;;;;;;;;;;;<4< ~< 4< 4<[<V<[<~<<<"2<#<$~<&<*<-8<2<4<DG<FG<GG<HG<J_<P<Q<RG<S<TG<U<VG<X<]<k<l4<mV<oV<p<r4<t2<u2<w<yV<{2<|4<}V<~<~<~<~<~<~<~<<<<<<<<G<G<G<G<G<G<G<G<G<G<G<G<G<<G<G<G<G<G<G<<<<<~<G<<G<G<<<G<G<G<<<<V<V<4<4<[<4<4<[<V<[<V<V<~==" =#=&=*=2=4=k=m=o=p=y=}==============>#>&>*>2>4>D>F>G>H>R>T>k>p>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>?V? V? V??#?&?*?-2?2?4?7?8?9?:?l:Al</l?>lDlFlGlHlRlTlmyloylyyl}yl[l[l[l[l[l[l[l/llllllllllllllllllll[lllll/lylyljljlyljlylyl[mym m ym ymjmjmm$m7Gm9m;mr:Ar</r?>rDrFrGrHrRrTrmyroyryyr}yr[r[r[r[r[r[r[r/rrrrrrrrrrrrrrrrrrrr[rrrrr/ryryrjrjryrjryryr[t etet$et9Ft:Ft<(t?Ftetetetetetetet(tet(teu eueu$eu9Fu:Fu<(u?Fueueueueueueueu(ueu(ueyyy y yy yyjyjyy$y7Gy9y;y|:A|</|?>|D|F|G|H|R|T|my|oy|yy|}y|[|[|[|[|[|[|[|/||||||||||||||||||||[|||||/|y|y|j|j|y|j|y|y|[}y} } y} y}j}j}}$}7G}9};}:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[ [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[= = =I#&*247A9=:m:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[ [jyj[$[9>:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[= = =I#&*247A9=:m:A</?>DFGHRTmyoyyy}y[[[[[[[/[/yyjjyjyy[V V V#&*-224789:tTn<4t@x  n L r  l  B l  "^NR@ P :jrN"jPj@ jjdd$  n !*!|"f"#&#V#p$@$Z$$%`&& &v&&'6'|'( ()$)*X*d*p*|****+++++++++,>,J,V,b,n,z,,-<-H-T-`-l-x-.j.v...../0<0H0T0`0l0x0001 121D1V1h1z112j2|22223,3>34r4~445556.6:6L7:77888 8,888J8V8h8t89l9999:&:t:; ;>;;;;<"(>T>???@@@AjABBBBBBCjCDBDDEE`EzEFFFGG(GJGxGGHHDHHHd"/n   /(0B B Q - 2E w9 S g  { ^   P   `U    0  d   4  Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.Lato LightItalictyPolandLukaszDziedzic: Lato Light Italic: 2013Lato Light ItalicVersion 1.105; Western+Polish opensourceLato-LightItalicLato is a trademark of tyPoland Lukasz Dziedzic.Lukasz DziedzicLato is a sanserif typeface family designed in the Summer 2010 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in 2010, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness.http://www.typoland.com/http://www.typoland.com/designers/Lukasz_Dziedzic/Copyright (c) 2013-2013 by tyPoland Lukasz Dziedzic (http://www.typoland.com/) with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1 (http://scripts.sil.org/OFL).http://scripts.sil.org/OFLCopyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.Lato LightItalictyPolandLukaszDziedzic: Lato Light Italic: 2013Lato-LightItalicVersion 1.105; Western+Polish opensourceLato is a trademark of tyPoland Lukasz Dziedzic.Lukasz DziedzicLato is a sanserif typeface family designed in the Summer 2010 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in 2010, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness.http://www.typoland.com/http://www.typoland.com/designers/Lukasz_Dziedzic/Copyright (c) 2013-2013 by tyPoland Lukasz Dziedzic (http://www.typoland.com/) with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1 (http://scripts.sil.org/OFL).http://scripts.sil.org/OFLLatoLight ItalicXA  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#NULLuni00A0uni00ADmacronperiodcenteredAogonekaogonekEogonekeogonekNacutenacuteSacutesacuteZacutezacute Zdotaccent zdotaccentuni02C9EuroDeltauni2669undercommaaccent grave.case dieresis.case macron.case acute.casecircumflex.case caron.case breve.casedotaccent.case ring.case tilde.casehungarumlaut.case caron.salt_K_KVV, `f-, d P&ZE[X!#!X PPX!@Y 8PX!8YY Ead(PX! E 0PX!0Y PX f a PX` PX! ` 6PX!6``YYY+YY#PXeYY-, E %ad CPX#B#B!!Y`-,#!#! dbB #B *! C +0%QX`PaRYX#Y! @SX+!@Y#PXeY-,C+C`B-,#B# #Bab`*-, E EcEb`D`-, E +#%` E#a d PX!0PX @YY#PXeY%#aDD`-,EaD- ,` CJPX #BY CJRX #BY- , b c#a C` ` #B#- ,KTXDY$ e#x- ,KQXKSXDY!Y$e#x- , CUX CaB +YC%B %B %B# %PXC`%B #a *!#a #a *!C`%B%a *!Y CG CG`b EcEb`#DC>C`B-,ETX #B `a  BB` +m+"Y-,+-,+-,+-,+-,+-,+-,+-,+-,+-, +-,+ETX #B `a  BB` +m+"Y-,+-,+-,+-,+-,+-,+- ,+-!,+-",+-#, +-$, <`-%, ` ` C#`C%a`$*!-&,%+%*-', G EcEb`#a8# UX G EcEb`#a8!Y-(,ETX'*0"Y-),+ETX'*0"Y-*, 5`-+,EcEb+EcEb+D>#8**-,, < G EcEb`Ca8--,.<-., < G EcEb`CaCc8-/,% . G#B%IG#G#a Xb!Y#B.*-0,%%G#G#aE+e.# <8-1,%% .G#G#a #BE+ `PX @QX  &YBB# C #G#G#a#F`Cb` + a C`d#CadPXCaC`Y%ba# &#Fa8#CF%CG#G#a` Cb`# +#C`+%a%b&a %`d#%`dPX!#!Y# &#Fa8Y-2, & .G#G#a#<8-3, #B F#G+#a8-4,%%G#G#aTX. <#!%%G#G#a %%G#G#a%%I%aEc# Xb!YcEb`#.# <8#!Y-5, C .G#G#a ` `fb# <8-6,# .F%FRX ,1+!# <#B#8&+C.&+-?, G#B.,*-@, G#B.,*-A,-*-B,/*-C,E# . F#a8&+-D,#BC+-E,<+-F,<+-G,<+-H,<+-I,=+-J,=+-K,=+-L,=+-M,9+-N,9+-O,9+-P,9+-Q,;+-R,;+-S,;+-T,;+-U,>+-V,>+-W,>+-X,>+-Y,:+-Z,:+-[,:+-\,:+-],2+.&+-^,2+6+-_,2+7+-`,2+8+-a,3+.&+-b,3+6+-c,3+7+-d,3+8+-e,4+.&+-f,4+6+-g,4+7+-h,4+8+-i,5+.&+-j,5+6+-k,5+7+-l,5+8+-m,+e$Px0-KKRXYc #D#pE (`f UX%aEc#b#D * **Y( ERD *D$QX@XD&QXXDYYYYDPK!I;generator/template/darkfish/fonts/SourceCodePro-Regular.ttfnu[pBASEe]FDSIGGDEFGPOS\GSUB]dJOS/2x`cmapspB3fglyfMQ.head:6hhea34$hmtx  Bloca'`ӄA BmaxpTaX nameܝpost+9  K4_< sK?:$X?? *eXXKX^2#   8ADBO@ ` X> cAWr5O_QbHR0f0dC*O+ 6&AQ]P<DgH]Z7jJ:]<]<GEM3@1G cAAAAAWWWW rrrrrrrrsrrrrrrrrr555555555OOOO ____________Qbbb|7 HHHRRRRRRRR000000000000000000000000$$!dddddddCCCCCCCCN******OOOOOOOOOOOOOOOOOOOOOOO+ &&&&&&&&AAAAAA e;UpDYQQQQQQQQQQQQQQIQQQQQQQQ]PPPPP6<<<<DDDDDDDDDDDDDDDDDDHHHHHHHH]]']ZZZZZZZZZZZZ7jjjjJJJJJJJ#:::]]]]]]]]<<<<<<<<<<<<5<<<<<<<<<<<<< f@GGGGGGGGXgEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM311111111GGGGGG<]]7]P^]]=P<<?<sE[>=7<<N3<M]]]ZV8JJJO**:]`<!,???ccG886E2M319GG;0GYGRT<R<<<<<<<<<<<<<<9<<<<<<<<<<<<<<<<<<ccccccccccccccZcZc8cccccccc-cc c+rAO0_b+HRF0OfK*&6,&$_(&9]0A[t]HQd8T/\@]<BO,85"Z]O,%9[]QQ@OO"QOd>[D    ccr>NNfHO0OfA*/6OA(&7b.,rrBC__Q'fN/K0&<>fOA&&6A[_ r;N00//QKh*D>ddn@]<]]PB1 @^X::#F}=,7DDPGZZ7:nd1g)<FH>n!]P33@X]JQDEd<<11<<Uccc*GaE9'8MFDCGaGaE9'8NFDCGaGaE9'8MFDCGa my^ffR`UUUPPuuu<<>fzbxcccT[H]W^tbbbbbp11WhUF4=:UM5:q1`N.*m*T=`l-77*E0SUUfUUUxkUUUoULLUU`UTL >+& FOF4t!!`QVg!!U<J>WII!>>>>>>**D3M  -<`15 {kj# o{ ?f5Y!!KK, ,,M49cS-$,$  Rklmnopqrstuv  !"#$%&'()*+,-./012345:=R^ *)+-KJLNipoqsrVSMT&(uWo69hUl8_7a]~U /9@Z`z~7C\ghnv{~  *,14=E_auz~/_cuCIMPRX[!+;IScgo    " & 0 3 5 : ? D I q y  !!!! !"!&!.!^!!!!""""""""")"+"7"H"a"e###!%%%%%%%%%%&&&<&@&B&`&c&f&k''R'd'..% 0:A[a{7CP^hjox}#,.49@_atz~0brCGMORV[  $2>RXfl~    & / 2 5 9 < D G p t } !!!! !"!&!.!P!!!!""""""""")"+"7"H"`"d###%%%%%%%%%%&&&:&@&B&`&c&e&j''R'd'.."=oY xpo%$#$    ;:.-iodcj$~|yzzTiplG%s޺ޚޙrmcݹjqվջ%y%l  "",028>HNPZ\^bfprxzz||xz RkloVSQT&(mno6789:=MR]^_a~ )*+-JKLNiopqrs;< @ S T!V#U"W$[(b.c/d1e0`,p<q=r>s?xC}IMOTQUVWZ[]\bafjhntuWw? PvOt@wo;g> N2:?AH4;@I   "-./02467C#JEvwxy|~z}JKLMNOPQRS T U V W XYZ[\]^_`abcd*,-358<=QX%Y&Z'n:uAzEyD{G|HXY^_`cdeklmFABCDEFGHIJKLf2g3h4i5j6k7l8m9RSxyz{|}~l16gY]Uebckx}~pqrstuvwyz{| $ !!""##$$R%%k&&l''()**++,,--..//09m:;<<==>>??@@AZ[[\\]]^^__``az{{||}}~~oVSQT&(m6=MR]a~ )-JNio;< @ S T  !  V  #  U  "W$[(b.c/d1e0`,p<q=  r!!>""s##?$$x%%C&&}''I(())M**++O,,--T..//Q0011U22334455V6677W88Z99::[;;<<]==>>\??@@bAABBaCCDDfEEFFjGGHHhIInJJKKLLMMtNNOOPPQQuRRSSTTUUVVWWXXYYZZ[[\\]]^^__``aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~\Ww? PvOt@wo;g> N77CCPPPQQRXY\^ghhjjknovx{}~02:?AH4;@I           " $#&-''2((4)*6,,8.1944=9=>@@AABBCCC#DDJEEE__FaaGtuzz~~vw{|~^oz}/0_bbccJrrssKttuuLMNOPQRS T U V W XYZ[\]^_`abcdCC)GG*HI,MM/OO3PP5RR7VV8WX<[[>+.BQ  X  %Y&Z'n:  u!!A$$z%%E&&y''D(({))G**|++H2233X4455Y6677^8899_::;;`>>??c@@AAdBBCCeDDEEkFFGGlHHIImRRSSXXYYZZ[[\\]]^^__``aabbccffggllmmnnoo~~FABCDEFGHIJKLf2g3h4i5j6k7l8m9RSxyz{|}~  p                       ! " " & & / / 0 0l 2 3 5 5 9 : < < = = > ? D Dh G G H H I I p p q q1 t y } ~  6   F X g Y Z \ ] U d ^ ` e b f!!!!!!k!!! ! !"!"!&!&!.!.!P!Px!Q!R}!S!Zp![!^y!!!!!!!!!!!!""""""""""""""""i""""""""")")"+"+"7"7"H"H"`"`"a"a"d"e####### #!%%s%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&&&&:&;&<&<&@&@&B&B&`&`&c&c&e&e&f&f&j&k'''R'R'd'd''...".%**M'>St<x4qBqg*VAc$/:EP[fq|  ! , 7 B M [ f q |  " - 8 C N Y d o z  : E P [ f q | ? J U ` l w # . 9 D O Z e p { (3>IT_ju'2=K ;FQ\gr)4?JUp{"-8CNY'2=HS^itHjZe  +6D #.9u mx  +6BNYdp{ .9DOZs~$/:EP[f>IT_ju[f  +6ALWb <GR]hs~    & Z e p { ! !!!!,!7!B!M!X!c!!""6"y""#+#^##$$]$$% %%F%%%&&?&&''E'''(!()(4(I(T(n(z(() ))N)))*)*P***++7+g++++,N,z,,,-(-a---..2.[../+/o//0 060c000011 11"1-181C1N1111111122 22!2,2:2222222222233 33#3.393D3O3Z3e3p3{33334 4H4Z4e4q4|4444445585@5H5W5w55555555566!636;6S6[6c66667%7B7`7}777788c889$9d999::O:v::;%;Q;;;<(>3>>>I>T>_>j>u>>>>>??D?\??????????@ @@@#@+@3@;@C@K@S@[@c@k@s@{@@@@@@AA3ATAAAAABB6B>BBBBCCGCOCWC_CgCoCwCCCCCDD4DPDtDDDEEDELETEEEEEEEF$FNFqF|FFFFGG/GAGYGGHHDHaHHHHIIZOZZZzZZZZZZZ[[[[%[-[5[A[M[Y[a[j[[[[[[\\\.\D\U\k\\\\\\\]]!]2]s]]]]]^^)^O^^^^_L__`/`m`|```````aaamabb2bbc#cScqc}cccccdddd#d,d5d>dGdPdYdbdkdddee!eMeeef#f?f\frffffg$gqyqrr\rrssWssttDtztttuuu!u)u9uuuuuuvvv&v6vFvVvfvvvvvvvw w w-wFwsw|wwwwwwxx$xDxlxwxxxxyyzFzNzqzzzz{{Y{{{{{||3|N|h||||}}$}H}d}}}}}}~~~-~>~U~f~}~~~5mez'@(h;\yĄ *2:BJYaiqdžɆ׆%KXemuЇAfʈAVk̉(Bbjz͊݊ (B]z݋ (OhxЌ، $P|Վ.rɎ-Ga{Ckّ>{ܒ+Nq0jjjjjw͓!>]{͔ݔ.=M]m|Ε 1DYnі!7L_r×ח0H`yŘߘ+C\třٙ*CXmȚݚ #<[s›ٛ)HjҜ"2CgtÝН&2?LYfsΞ۞(ͦۦ'8IWm~~~ŧ)LTat> 3!%!''#7'377#>I46u1BBal:ggP^ww 8 3'&&'#3#'#! ^X>?odd7m99mZpc#"332#32654&##32654&##cCe98;HPnvYTIML]jT][Vj F:1O NDa_|675,;C=5A*"&&546632&&#"3267_QLLU;\/B)?]44]?-H/'c QkjR0 5!AvRRyB-2W)332#'32654&##WSIqooqID||r 3!!!!!rLFGG 3!!!!FF5"&&546632&&#"3275#53QRIKUAX/?/=\3iaI)e QkjR35"AvR|'E-O  33!3#!OTTTp5_ 353#5!#3_GFFGQ"&'73265!5!7j"4K&GAf)^ 583,+KQrFA=e<bD 3333#bT_^qIiX33!REGH33373#4667##'#Hf\ ]fP%^<\&jjpH WUUW R333&&53#'#R\? P\? d1k4Tp2h30("&&546632'2654&#",Jr@@rJJr@@rJK[[KK[[ RljPPjlRI~||~f 332##32654&##fIm==nHsiVSTUi$UHEZ,HAFG70]+ &%2654&#""&'&&5466323267,K[[KK[[Wn_u@rJJr@p\J3 %9||XBjPPj+*Cd)332##32654&##dCg;PC_umMQQMm#QDL]Y?@A4C-"&'732654&&''.546632&&#"1Hz,2%c8DK5"^!A,7a?>h$, N39F#6\)A'8h 5,:%-:.#*) *B02O--$6!4,( (-A14U2*.!#5!#JFFO "&&53326653-@e9T$?'(>%Q9c 4r^fDQ$$QDh^r4+- 3336673XjiU:e::e:bp N%333>7733>73#&&'#nd^0 @P> .Z`h@  @d-/!!/,,/!!/,o::6"33366773#'&&'#6ķ\\  ZX\c  bS=,,33&2!53366773Xc$&_V%L((L&ZA 35!5!!Ant2F2GQ'"&&54667.#"'6632#'#'2675-K-G}8//Y" %s@daC(d)S)hw1A !>+7I, !7"%8.m[B/B&"!1 )%]!"&'##336632'2654&#"@#Q#BR!W+bh>dG@T@I I&#G #6^"(qSv>EgZPc#&P"&&546632&&#"3267ZLxFJ|I;X)A&8U0/T8-K%(c !Z8@-EI/S8WcD"!&&"&&546632!3267><^ 6N2IwFFqAiuiL,G!$]MHKJC)Yl> D;,C]H 60<L"&5475&&54675&&5466323##"&'3322654&#"2654&##"&'(jvP#5W3)~2U5+50m^[ByX/AA/.BB9Ub78_%"QG@>. &1@+5N+ C44K( 4>-N/?43??34?<%#)&-] 3336632#4&#"]R&W9VRR4<+D+s)6d`#EC,,Z&U 07'& 0j> 3333#'jR^\sqJ"&5#53327MS5++0"8 YVC50=:.!33366326632#4#"#4&#":B2*G3*39R4!L%@"*T'-MIVU%&V*+%&] 3336632#4&#"]D&X9VRR4<+D+S)6d`#EC,,<"&&546632'2654&#",@mCCm@@mCCm@FUUFFUU d;"O AU@I I&#F> *qRv>!\gZPc#&<3!57##"&546632373275&&#"Q-^t?e9,H"BHA!? *E)LͱZ+yOs>" 6MI/S8Wc3336632&&#"D&pC/$7e,s;D G ?LG("&'732654&&'&&54632&&#"6G|,&*fC>=AB^`fd8h$("R/>2CJQW!2` -6$- C7;O%5*"*6%'B(E""&&55#57733#3267GR# D5F#8!I 3Z<>CAD < M"&5332673#'#WRS3=*E(RC%X d`.EC+/QU+63% !336673Sp  pO%G##G%P3336677336673#'&'#rjR: ?2(0i2*.!(2dd7m99mZp 8M& _ %3'&&'#"&54667#'##33267!  +<(>?U^&5  .odd7m99my-.3' p>% + )8&- 8h& 8x&T 8x&V 8&X 8&Z )8F&&- 8&\ 8&^ 8&` 8&b )8J&& -O3#!#3#3!5#.+?IywL6jRFGGOc&MxO&Mx)!*35#5732#'32654&##3#532654&##iOOCe98;HPnvjT][VjYTIML]8 F:1O NDa_F;C=5V>675,cV#&<A*&32A*c&.A*F&.A*M&.A*;&.W)M&W))&-WV)&<W)&3 )73&&546632#'32654&'9:'%(3;8oRzRVZcS P70::XEAd:Dzrc&rc&rF&rM&r0&r&rJ& r;&s) "&5467!!!!!!#3267,;5!K0" --.-FFGG#2 +r)&-!rh&rI&r*x&Trx&Vr&Xr&Zr)F&&-!r&f5c&5F&5J& 5;&5&05M&5&5I&5M$1&&#"3275#53#"&&546632&54632&&#" /?/=\3iaI)e@RIKU'>1  L5"AvR|'E-QkjR/:?'O F& O 0& O) & - & 3NO & 9 N3#5753!533##!!5!OEETTEET8nnnn>5}g_c& _c& _F& _I& _0& _& _;& _M& _"&5467#53#5!#3#32677+<.&$" --.*DGFFG< +_h& _)& -_J&  QF& bD& 0&b)D& -&bVD& <&|c& & |& 01)& -17)& &-1V& <1  35'737!_|RE45Bdq5G&  Hc&H;&H)&-Rc& Rc& RM& RI& R&0R;& R)&-RV&<0(c&0(c&0(F&0(I&0(0&0(&0(l&0(J& 0(M&0(!-"&5467.54663232672654&#">,;+Mk6@rJJr@^W.." -/K[[KK[[-.(<\^iQQi%@ +||0)(&-0(h&0(x&T0(x&V0(&X0(&Z0)(F&&-02-'"&&546632654'7'2654&#",Jr@@rJ>1NA 80,2@rJK[[KK[[ RljPF*3? +]lRI~||~02c&02c&02h&02I&0)2-&-0(&f$0'77&&5466327#"'&#"2654'$C@rJWA48@@rJYA6*,>K[K[+b+tFjP9M$^*rGlR/ 7+ 6)([_cnTFbD3Q/*.M&*.&3*.&0*).&-*V.&<*.!#5735#5!#3#Z4؎2:FF>O c&O c&O F&O I&O 0&O &O J& O p&O l&O M&O %"&5467&&533266533267>,;/]nTN;(?%QFD;-" --.+>~ffS$QDhjs> +O &PO &IO &RO &LO) &-O h&Ov9!"&&533266536654'7-@e9T$?'(>%!)+A ?.9c 4r^fDQ$$QD$*):8 ^r4Ovc&Ovc&Ovh&OvI&O)v9&-+)-&- Nc& Nc& NF& N0&&2c&&2c&&2F&&20&&2;&&)2&-&2h&&2I&Ac&AM&A;&AF&A)&- AV&<  ) 3#5732#'32654&##3#WKKSIpoopI:8D||>e!3332##532654&##eTvIl==mHvkVTUUkn%THEZ,AFG6;& "&&5447!&&#"'6632'267!,Im;VP(C(W:Nob8)L K/uhcq06( M%4@{~Ep[33"&'732653pS%  &S?pB4,mJXD*333"&5463233DL!--!!//ELG-''++''-GY[9c&'nQ &Q &Q&Q&Q&Q&Q& Q&QK *5A"&5477"&&54667.#"'6632#'#'26752654&#"@4:/#I%):~-K-G}8//Y" %s@daC(d)S)hw1A^!!!!98(6a2#3"(8!>+7I, !7"%8.m[B/B&"!1 )%("!!"Q&Q%.9"&5467'##"&&54667.#"'663232672675+<8'(d4-K-G}8//Y" %s@da6/% /)S)hw1A./-D=/!>+7I, !7"%8.m[= '&"!1 )%Q)&-Q&Q+&SI&UQ&WQ#&YQ)&&-Q@&[Q@&]QP&_Q"&aQ)&& -U3@"3&"&'#"&5467&&#"'66326632!3267%3267&55%AH3K#P,7Iu0&=O+,>K(3B @90Aq)!>CLDQC.)).G=J\G98 /55/=e< LY 8#'#"6A "/U &U&)"&'###57533#36632'2654&#"@#Q#BIIR!W+bh>dG@T@I I&#G #62;VV@C["(lPq"Z8@.EI/S8Wc Q<)&-<^ 6N*-:+! IwFFqAiuiL,G!3=$ /MHKJn./(? &&0#j)>&&-#jV>&&<#j> 337%3#'jR^\snJ&'<J0&'J&'0UJ)&'-UJ)T&'&<-UJV&'@ 'gTThhTTg<)&*-<&*<&*S5&*U<&*W<#&*Y<)&*&-<&* <K&*e</)"&&5466326654&'7'2654&#",@mCCm@7.)-@ ?,(0Cm@FUUFFUU T4Rr<+=*>V5Pr<+iS?,< & U 772654&#""3&"&&5466326632#3267#"&',44,1333'61N-.N1.BH.0@ A1)=#1NB8hSShgUSgyKJC>:=e< SR 88==8 &-.f&-0&-.&- .)&--)&-&.-@V&-<G &.G&.G&.G-&.gG&.2G&.0 G&. G)&.- X43"&'732654.54>54&#"#4632*F !4*-)<<)$-)7?Rk^5I&$)<;)(I :/#*"2*"2+0 %1LJ\q)C(%6+*$%:/*C(gB3#5754632&&#"`dHD3 A:>)Yl> D;E"0&/E"&/2YE"&/0OE)"&/-OEV"&/C@ AD < M &0M &0M&0M&0M&0M&0M&0 M&0M&0M&0M&"&5467'##"&53326733267+<8'%X8WRS3=*E(R6/% /./+AU+6d`.EC+/Q: 'M&0OML&0HMH&0QML&0KM)&0-M&0MV!"&53326736654&'7#'#WRS3=*E($2@ :#C%X d`.EC+/Q*1 +:;7U+6MV &MV &MV&MV&M)V&-3)%&1-P &2P &2P&2P&21/' &41/' &41/'&41/'&41/'&4 1-'&4-1/'&41/'&4G &5G&5G&5 G&5G)&5-GV&5<<17326544'&&#""&&546632&&''7&&'77,J-PM#R'PS?mB;gB/T :,: &&I!v?M:k2K)oW  /&\9iHDe8*&Bd'N4B 4)F2==wPyD]3"336632#"&'#2654&#"]R"U+bi?d:$L @VAI H&#FW"(qRv>#\gZPc#&]I  "&'732654&#"#336632( &4<+D+RD&X9VR? ?7/1EC,,S)6d`N[7'"&'73265#5!&H9I24%X= F>C<\5]' +33"&54632"&'732653"&54632pR(##""$   %R<##""J   >3,JX#   l/"&5#533267"&54632"&5#533267@Ck$ #(!--!!//?Cl$ # YVC50>-''++''-YVC50>P'N 33"&'732653'7'7pR$   %R<+:+:>3,JX)8)8^%"&53366323267'>54&#"$dbD(d3.K-8F0Y" %shw1A**R) m[*B . >,RU2I%8. 1 )%%#] "&'##336632'2654&#"@$P#BDZ1bg>dH@UAI$J #E #6@-qSv>EfXSc%$]+"&'##4632&#"36632'2654&#"A$Q#BY[0!!62!W+bh>dG?UAH J%#G #6Sh ?>8z"(oRt=EeXOa#&="&'7326654&&#"'66328e'%M-8S/.O4+G*_BFtGFw ($5$/T78U/5*Z(E*5U1/g/:>YYC:,'  < eBRr<(30V9,G486-4H9;R-^s?d9,ES  F@!@)D(LI@d+yOs>"Z#)/?I/S8Wc<b -"&5466323'54632&&#"#'#'275&&#" ^s>d9+F@B  !DSFA!@ (D(K yOs>!Z8DM?2*@-EI/S8Wc? "!&&"&'73267!&&546632">U6 WP:]$"H+Kj:iE@kAGvJKHMC"6TR  Ef9>rPOr=< "&546632373#'#'275&&#"^t>f:+H"BDTHA!? *E)L yOs>" 6@-EI/S8Wcs& E "&&5467!&&#"'6632'267!)If5}^J+I!%]:Jp?@mEAWP e~B0)06_==a'!#K2@D5CLRRL1S$$.i MF48 8$,:"6%&J@%)+- 6(>!=+"&&546632'2654&##532654&#"GLxFIwD6W2+),Ar_=BG6#4:;13Q0c 9qSUr::-$: ;4FLB-*('@("&%.U=\_7'4"&'732655#575#5!3#&H9I24%X= F><CB<\5<(cu*7"&'732677##"&5466323'4632&#"275&&#"/`)%O%FHQ-^s?e9+F@C  !xaEA!@)D(L:F:a)sLo="0AQ?2*Zf!I .P4R`<' -"&'732677##"&&546632373275&&#"/b(&P%FLS->_5>e;+J BwdFC!@ )E*M;G:a);nLLo=#6[k"I.P4R`N!"&&546632&&#"32675#53SHwFIzGAU)?/2U3/R4!9a ;rRPr=*4"-T=;U-p;(3 %%"&5467336673'2654&'#.7=#TqpP#<8B4#G4"7""7" N4G#4B9";""="<#/"&5467&&#"'66326632&#"'2654&',UeH92-)K('M(-28IdV298(7daEB+,]I +"&'732654&#"#4632&#"36632( (4<+D+RY[0" 62&W9VR? ?7/*EB+,Sh ?>8(7daN[]'Z4&O 0V 353#5!#3VC`CCC8&Q 03 ##73753cUrRiMJ&'=J )354&#""&55#"&546325#533#327!#&  MSTH3'( 5++0"8n)&YV<.&0C@50=JI"&5#533267MR4+,!:YVC*5/ > O';#33!6#"&'7326654&#"'!ORE_1=a7K` )J7&=%F>",2Y7Fb304%%C->F,]33!R.]C*!#'##"'#"&53326733267B2*G3*39R4!L$@"*T'-MI\U&%`*+&%`*3"57##"'#"&5332673326731*G3*39R4!L$Rͬd%*T'-MI\U&%`*+&%`M:I.-"&'732654#"#4&#"#3366326632#  4!L%RB2*G3*39:?0(rU%&V*+%&@"*T'-MIFQI  "&'73265336632#4&#"8  D&W7VQR49+C*8?/)S)6d`#GA,,HS]Im "&54&#"#33663232670C84:+B+RD&V7VR  SH?GA,,S)6d`)/?`333&&553#&&'#`O$NO%;/[':/['<"&&546632"!&&267!,@nBBn@AmBBmA?U > V?DWX 9rSUq::qUSr9OGGOXOOX!K%"&&5466323#3#3#'267&&#"8]88]8-񾙙.##5JJ :rSTq:D@DC_\_a[,3,#5.54667534&'66:b< I"&&5336632&&#"3267MFR#D&pC/$7e,5F#8!H3Z<s;D G ?LAD < 354632&&#"uQ700S3yG (UDc!332#'#532654&##c5S0H3]7==7?6?G ľ++,$c!732654I##337==7]3H0S5S%+++ G?5@GI7"&'3267#"&55732654&&'&&54632&&#"6-T$$   $C;&*fC>=AB^`fd8h$("R/>2CJQW!2` 5'0=SOU6$- C7;O%5*"*6%'B(8'"&'732654632&&#"(>/3 LZ$4&7&F= B77Xd= B7Xc8'#"&'732655#5754632&&#"3#(>/3 LZ$4&7&F= B7:Xd= B7@Xc6d23#5#5354&#"'66GR# D4G"9!I2[<>CAD < EI""&&5#57733#3267FR# D5F#9!P3Z<>CnAD < J "&55#57533533##'#'32675#LH``RRffD"Nt,0&:" a]L:@L(0C='+p2&'"&&546675#53326654&'53#,Kk8+j+8#D33E"8+j+8j ?f82N;C5$bI-N//N-Ib$5C;N28f?M"&&53326654&#"'6632)?c:SR:2E$+- GU7l /dMXK;f@JM@diXO3% #&&'##XSp  pO%H""H%P#&&'##'&&'##33677jR: 32&&#"#&&'#14L4"   0=Sw  j*0M-A<.? J#"J!9!!53366773YU#!TXˤB:!!9 GIl"&55!5!5!!3267/D8FI  QB$,wC,_)/?GF &%"2232654&'667#5!5!3632##+  %&> D,N%9`'3NN- *2$ 5,wC,1)6H9;'!"&&'7326654&#"'!5!632 8U?(!U@-J,WP $!esDm,50&E.AI .C,kWGd4'j6C"&5466323'53!6232#"&'732654&#"'7##'#'2675&&#"CX.K+-L 0C#-L/1C'- )3-,!;5'"+5. xNs?],5Y6Ea3"4JK?E4]:+E*!gSVd: 0"&&55#57733632&&#"'2654.547#HVe+IL E&%A *#'99'l\G':;'}C ,S=> 0#(?2CN@-%%/"$4)A:0'[3"&'73265#3267#"&5#5773354632&&#"a#   "' -L=HK EAL  (<>3,-1> ZH >PIW?4,JXG3>54&#"'6632BR'NG9O,!gL?g=1U77%@D+=H1 5%;-YB:UF$Y!.546632&&#"7V0=f?Mg +O9FO'TA$FU:BY-;%5 1H=+D@%G35#5736654&#"'66323#LfS[KF:P,!iN>e<(B&:/f<=H25$<-YB/L=?R!5#573.546632&&#"3#LL&B(;e?Nh",P:FL\R:=L/BY-<$52H=l>< %"&54632'26654&#"7"&54632,mmnn.I+]EE]+I.%%%% D;oo;$##$R[ "&'73265#'##33&&53#    ? P\? P9B5+2h3d1k4TmKW<< &< &<&<&<&<&<& <&<K !.:"&5477"&546632373#'#'275&&#"2654&#"04:($J&):V^t>f:+H"BDTHA!? *E)LS!!!!98(3e2#3"(8yOs>" 6@-EI/S8Wc%"!!"<&<)&-<&<&S9&U<&W<#&Y<)&&-<@&[<@&]<P&_<"&a<)&& -<%2"&5467'##"&5466323733267275&&#"*94$T.^t>f:+H"B4*! -HA!? *E)L./+B@-yOs>" 6; 'I/S8Wc<'<' &6 <'&6 <'&6 <'&6 <'&61 <'&6 <'&6 <'&6 c4&@ c4 353#533cŭC`C]Cc4 &@c4 &@c4&@c4&@c4&@c4&@c4&@c4&N c4&@c)4&?-c4&@ c4&P Z"&5467##5!3267a,<3#4,,$ /./*BC; 'c4"&5467#53#533#3267Y+c43535#575#533#3cŴC:C@C8 &3267&&#"&&'#"&546325#5!z)%(0 : (M5FKB? B!4 /i/!B-,8C)?)c4 353#533cŭCBC{Cc4&R"<c40&Rc4&R0c)4&R-c)4T&R&"<-cV4&R<c4353'75#5373clC @6PCT6dC-{&R  \ #53#533353#533"&54632qkfilm####CBC{CCBC{C$"!!"c4&R=%c4 #354&#"535#"&546325#533#3!"#!xJA1'$ f *C4%!- C/C 8c#3!!F+-353%!&&'#+`YKa!!2^2G%5o99o5rAO  0(!"&&546632'26654&#"'53,Jr@@rJJr@@rJ2K)[KK[)K1 TiiQQiiTICyRzzRyCHH_ bD +- 33#&&'#+aXjipc:e::e:HRF 35!5!5!F6GG5GGFF0(O 3!#!OTpJfK 355!!!K_21FG*.&2>5&&5467534&'66kkLkkSIISTHHTXwuWWuwXbVmhTThum6",,!5&&55336553drPTPrdus Z su&2'3535.5466323#56654&&#"&y3!=rMNq=!2y1A&J66J&A1DPjB\RR\BjPD=/gGqAAqGg/=$8 3'&&'#3#'#'^X;;.9$Oodd7c;;cZp #  3!#3#3'@?9$OFGG #  3333##'LLL9$Op5 #  353#5!#3'vv@wwX9$OGFFG # _0( "&&54632'2654&#"'\;\4rYZrrZ8CC87CC9$O QlIH # (Z!53366773'eMI  KJ9$O)J&&L'Z # &200#'3535&&5466323#56654&#"'c)/2[=>[1/)c')?::?)'9$OD<^XOOX^<D=;_nn_;= # 9? 0"&5466323733267#"&5#'26677.#"Wm=d92[R  +4@O">* ,3%C*D wTv>8Gs@-? 03cE)E)[68,V@U]]M 346632#"&'72654&#"'>54&#"],ZD1W664J[8Z3.]&8OFG 5@@,8B#SBg<&L;6R dMA\0!)=v>JC:N? 1> 88XYXW.0M6654.'736673#no{K+c*A$1"&&54667.54632&&#"'32654&',U"a[,"&54675&&546632&#"3267&"#"3267@j{A.+,6_=6b)!IU=EDI%MO-R+#5c ND57 :"-: 74&&!(DP(/"7(tH ('6654&&'.54>7""5!#B945]86Yo9HPKy;q[6(K3PM $ /]O54&#"#4&'336632,2-G-RK)Y;NEPFD>*=aB&_83a]H "&54632"!&&2667!,jzzjjzzj=Q&R=)@('A ||4yffy4Q "&5#533267QH0.,< YVCRH41 = dA 34&'33>7.'nR(o}> /c1MV(]FC#!%aH > FrNN 8*3nh,"V_0&-6]8)''&&#"'6632##Y9- + 3G5YG? D ,ZGTE'&33266733267#"&'##"&'TR1611S  &'P,!7CE.,BbW>.:42 2JB(/!&&'73>73tCR&H9 "=,S 7Q5]4H?ATW\H:'6654&&'.546675&&5467"5!#"3267&&#"B858`9,I*0?)%+-7Q)@!!%-R4.P2SG $ )L@0O7 H4)?CC>:#6H"B/05 *2F@"&&546632'2654&#",@kAAk@@kAAk@FQQFFQQ 5#'665#57!#327:0R eE\-  ?;FX[(fkkb?D)_ZF0?]M!46632#"&'726654&#"]=g>kr=a6*Q#'@&AJ&B(#IUn7tRv>(AjA.Wi?Bk=+I*/5.?TS :pPUn5FcDKk9D`R1S4Y[TbB"&5#57!#3267xA4F 0 GD$>CNE"@ O!"&54654&'332654&'7&bqP&=$@TP;i hi'N'B&8 &e*1<bg3l?;w=Wy?,M,n#5.54667534&'66:b<qA|"6."&546732654&'332654&&'7#"&'#BZ5&H)*.#(U($,"I&1UE#;8 xyM9!=qMLR7C=''=F4TW2MH):{Uzz'**'ZL %'6654&&'.546632&&#"B./9hAHvC=U*<)2P./Q2:?!, 4aONm9'5,O59D% +"M] )5".546632'2654&#"6654&#"I(TE+-[E/V6<5P\:a?;MEHH? 15g@*;@ 7ZBBh;%M;6TiO>Z1HL:;Q #6E'!6W@88YO +7&&""&54&'332667.546632@pVZH5E\hMH3)@'kS#6Z6|:g >. x>c_'/3"J>0|qBR&7R-H,M,n%M3 )6654&#"5.546754632S>N'&#O:f?=.@+/P>S@JR>e;+=y>fWS`;۪9nQK604dDQ\k_qPs?+V*9?&[&$]M&Q &Q &@&O&O&"6&Q &JO&JdEA&34&'33>7'667.'nR(o}> /c1MV(!I_'FFB#!%aH > FrNN 8*3nh,4d#)X+"U_0&-6]>M %2654&#"5.546632,HQQHHQQ#8\5AlAAlA4Y86gUUggUUg?kIRr<&E}Gx+=F2`+T}` }h73Q#\W3773#6\ /c')9$O # 4J 7E"&53327Z3,S   ;61PH><|#<|#>p!.M //m/j/l/i2'n2'kA3M4JL&Nx'6654&'7 !*)BI3& /.,#-w.5467S3IA )*!-#,./ _'7(2L c '6654'7'7 B6@92K& 5/0.,5  &&5467'7"9A5 Cl2K 5,.0/5 &  '6654'7'7 B6@97L& 5/0.,5  &&54677"9A5 C9L2 5,.0/5  #"&&#"'66323267'6654&'7] * ! * m %;?:P ## ##! '! #&&54677"&&#"'66323267G$:@:%  * ! * !' x ## ## 8c# 3!!32#'32654&##c~Fk>ltTSUTrF$OBg`F9C?5c#`DB !#'53>7>7!3#5!"     9I Ix%Tk8ZZ2-cWAimF2ѼrW/3'&&#"'66323337>32&&#"####+   ,%/5L5/#*   +Zn+"&'7326654&##532654&#"'6632-Hu2/,Y:,G+^VJ6XNK8.P-$k=^u3/9K@l .39+&:)?<@:745"8#-YO4O SD?X/N 33373#467#NP ?\P ?4k1pW3h2dN E& fD3337>32&&#"##fSkX-/ Q\k25N $$5 "&'732667667!##: ":T+6 MKNjnpJZZdk(HO  0(O mfA**./,"&'7326773373 ' Yz2/pUL K#܁$=F>5&&5467534&'66p||pLq{{qMOOMMOOM _qo}]]}oq_XR`l]PP]`6"ODM 33!33#5OSSG DI2ѼA!#"&&55332673<(Km:RWP':T&)_PS@%p(0 333333(LLLIIp&DP3333333#5&JJJ@ BII2Ѽ= 3#5!32#'32654&##ɶ 7Ci=zh>3MPTP,JF'QAiaD>F<<7! 3332#'32654&##37L$byvd%KMMMRLWbiaD>F>:pb! 3332#'32654&##bTyHm=nzoSWVVm&QBiaD>F>:."&'73267!5!&&#"'6632Ch)."O3Vh dV+K.h=S|EG} 2-4"(||Gho!6 1NooM,4 %2654&#""&'##336632|/33/-55-O_JTTK^LTdd=~ww~I핊!##&&54663335#"y`AT;hCnnLRR[ODQ#pY4A@?rc]r0a@#"&'7326654&#"##5!#6632$  ,ND2*T7>a80K C;4JC JFF+\JNY%c&B*"&&546632&&#"!!3267`SIKT<^.D)Xl l]/J.'c MooN1 6"ohG||("4-2C_ _0Q > )"&'732667667332###%32654&###     Wml[_\ !0A?@C MFIljWbiaJYh\b%P>F>:'=333332###732654&##'LL#WliYp?@AAWbia5D=G@875!#6632#54&#"#7bmRED2*SJFFZfC8 JfDc&N c&/,E& KD  33!3##5KTTEIp'3#53533#32#'32654&##SBHm=~nH>SQSX7D}}D"L?i]B;E>50("&&546632"!&&267!,Jr@@rJKq@@qKFYNYFJ[[ PmmNNmmPbqjjqzz&W33366776632&&#"Yj@:4  :e::e:IB M%%<3!73!9F < 3#57!!3#PPҨ,:&F>Dg43'&&#"'66323337>32&&#"3#5####+   ,%/5L5/#*   +o- ;'nD-5&'7326654&##532654&#"'6632uU/,Y:,G+^VJ6XNK8.P-$k=^u3/9K3X8 V9+&:)?<@:745"8#-YO4O SD8R2fDL3337>32&&#"3#5##fSkX-/ Q5 Bk25N $$2Ѽ5X3#5!37>32&#"##ͺBK'*  IQ@JF44M #%5ODM33!33#5#!OTSG @Q2Ѽ5AD* 5.546632&&#"32679Hp@LU;\/B)?]44]?-H/ N2 UcjR0 5!AvRRyB%/&2&2!5#57333667733#Y&Xc$&_V:v%L((L&>6D4333667733#5#'&&'#6ķ\\  ZX<A%c  bS=,,2Ѽ33ADF!#"&&553326733#5;(Jl9RVO&8TG F&)_PS@%2Ѽ[336632#54&#"[S9&Kk9RTP%7)^OS>_ WE& 8E& OMrE& ;&N &0(0&0(/,&/,l&QK.32654&#""&54>7>76632NMAGGB%P%p|,RrG#6!;W;!!Z/<[39dd{gRKY&2 ӥyT)  K  .WI()6fGMr>h 332#32654&##32654##hTi.'+?qYB97>B?9B(4  65HC%""&(L 3!!yC]*T-73#'53>77!3#5!  FG GHZ`4#SN]4D R,3'&&#""'6632353376632&"#"#'##5#"  '<*7P7*;'  "Vi?P?i])M*&"&'732654&##53254#"'6632;k4$*X-LRMITH4L&"*c@\vW2= *6"-*)&@KJ7"@CK! 75FLd3336673#5467#dP% LP %']/;'^/<d&" n03337>32&#"#'#nR;&*  5[l*-M)a"&'73267667!##J      GS L16OOCC@#33366773#54667##'&&'#@d\    ZdN  X>\  ::;>==>;] 33353#5#]RRR<*]3!##]R]]3+PB!#5!#CC]1/'4 38#.:57#"&546632'536632#"&'27&#"32654&#"'CS*E''P.DJ*E() #%.+),#/!!!͛J yOs>JLqRv>J#0!gTVcgZPc"@3^T8 33333#5^RRGG]]4X!5#"&553326753*&dmREK+RSazz=4: 333333:RzLzR]]:TR3333333#5:RvLvR<A]]]4#' 3#5332#'3254&##ɦJWkkWJBy;>BCHPQJBY.*F 3332#'3254&##3FKDQbbQD5|q,,49VV>Br(6qX%  &1P"&&546632&&#"!!3267ZLyEJ|ICCttCHPQJBY.*<F033366776632&#"Ta    051   p#I##H$HDJ$%3!73#B]H  35#575!!3#JJy٬8C>T_13'&&#""'6632353376632&"#"3#5#'##5#"  '<*7P7*;'  "b/:!i?P?i])M*T)'&&'732654&##53254#"'66321[,$*X-LRMITH4L&"*c@\vW2=eT  $6"-*)&@KJ7"@CK! 75=KnT=3337>32&#"3#5#'#nR;&*  5<?!l*-M)a4!F3#53376632&#"#'#ʩ_*:%  'O_ClA'M+e]T8333533#5#5#]RRGGJ]4PT'.546632&&#"3267/@c9J|I;X)A&8U0/T8-K%FX @jHRr<*5/U87T/$5> 33%5336673Tn  nP%J""J% 33%5#5733366733#N9Tn  nP8%J""J% X>@T037'33667733#5#'&&'#@[M  IWLG$U!Pk+,i4p.+pXT+!5#"&5533267533#5(&blRDI)RGGR^~~:3]4] #R&  J'Q& UD& Ed&" <&(<1/'&-1/'&-<<&e U&3"&&5467.54667>7'32654&''7`;iW"?(9iH(-6FT%(@$-E(6c&>#BJ=.NZ 4aB\n-12/  K  #BT;Dj;-C&]I54&#"'66326633IlMDG-M/+dC`pJW=1`t57F- /,5gU<{OG9*"&'732654춮&#"'6632Rq#* Z=AXj~q`G;-P ,(g=<_8M;+G,?h 7#6.@59F?E2/6$4#-&H4:J +B,8R,'!~ 735667#5!533#"A?Xcc=/47tB8 ~!"&'7326654&#"'!!6632Ul%) T@-J+VG(8",i5%=c;Cl 6!6-$B,BJ3G +XEEa2M )"32654&"&&54>32&&#"6632@&W& UF9NFAEo@,K`4;X.B$3W7'^0Yn;aH(.\aM?AFDf`U''34wg&-cb=\4F~3>7!5!1M7?S0[CG3H^D*7"&&546675&&546632654&#"2654&&'.Hi9(?"(93Y9^h9(#9!6fPB?5C-MGM5[8.?X -P2,@.J21J)`J-O+<./N-h:F/B8/&2#?1-3"B05EC  )3267&&#""&'732667#"&546632EC&V' SG9Np:X .B%3V7']1Xn;a8FnA,K`AF(-]aM'44xf&,cb=\4Dg`U'G "&54632"6654&267,j{{jkzzkC(UC 8 U W;E)~[F)a~ 353'733at*@DV0DGJ #"&54632'2654&#"7"&54632,j{{jkzzkCUUCCUUC%%%% Bsywnnwys$##$a> 353#566733a8M=D5DE J356654&#"'66326633IDG-M/+dC`p>1n@:H- /,5iXL\G9J*"&'732654춮&#"'6632Rq#* Z=AXj~q`G;-P ,(g=<_8M;+G,?hV7#6-A7;E@E4/8$4#-'I4:L +C-:S-'!> 735667#5!533#!@?Xcc=1.7cC8 >!"&'7326654&#"'!!6632Ul%) T@-J+VG(8",i5%=c;ClV6"5,$C.DJ7G *YGFb4NsF>>7!5!1M7?S0J\DG3I`DuC J )3267&&#""&'732667#"&546632EC&V'UH9Np:X .B%2V7']1Xn;a8FnA,K`zCJ(.aeN'33xg%-gd>^4DgcW(GJ "&54632"654&27,j{{jkzzk2UC;'U 7Syp(+K4S|sa> 353'733an*@DR/DG #"&54632'2654&#"7"&54632,j{{jkzzkCUUCCUUC%%%% B# "" #a 353#566733a8M=D4DE 35>54&#"'66326633ImMDG-M/+dC`pJW>1`v5>N, .,5p\<{PG9*"&'732654춮&#"'6632Rq#* Z=AXj~q`G;-P ,(g=<_8M;+G,?h 7#6.B9;G?H418$4#,'J50%7fB8 !"&'7326654&#"'!!6632Ul%) T@-J+VG(8",i5%=c;Cl 6!90%D.DL32&&#"6632@&W' UF9NFAEo@,K`4;X.B$3W7&_0Yn;aQ(.aePADGFicV(&36|j',ed>_5F3>7!5!1M8@S0^EF2JaD*7"&&546675&&546632654&#"2654&&'.Hi9(?"(93Y9^h8)#9!6fPB?5C-MGM5[8/>X /R4-B/M42K*aL/S+>/1P/q>  .0 ,.]4P;&%%'E;Xy}'f+'f 8 #"&546323"&546323"&54632f))(()))))))) *!"))"!**!"))"!**!"))"!*u%'3"&54632 P ++++X^^*$#))#$*Hu73"&54632 8 (++++^X^)$#**#$)m%7&>54&#"'6632"&5463213$77&A1"\:Sg$52+++++@3/1)8-#.UG);10:'*$#))#$*y<%"&54>'33267"&546323Sg$52I13$77&A1"\3++++UG);10:'+@3/1)7-#.)$#**#$)`c''3n`nn`&s^|"&5467632+'3MC.6 '*^@8Kx"0O4( "+^'667#"&54632/6 (* (2L^0P4(#+@9Kv^^&sf^&s{f{'s^&&54632#"'cCL2( *'  7.^#vK9@+#(4P4%'57^'4P#47'7'7''4"#PR4&s`4&sU+iU+iU+iP 75!PHHX 55!XHHP 75!PHHX }s%"&&546632,'D**D'(C**Cs%B,,B%%B,,B%g%"&&546632'2654&#",/I))I//I))I//;;/.<11>>11>7!  u7!'35#$u"-753%uu753%3'umuF+e73%eDO7377'G)OoKmlc%5!+Bc%uN%5!'7#+nmNFTe%%5%3%euO%%5%3'5G+OKls7!'2654&#"(;MM;:NNs& M:;LL;:MX455!Xpp>z==>Aw5!>A66f "&'73267,e_mm_dB>):55:)>BP &&5467hyyh-d``dQ䑑Q*U~~UzP '6654&'7-e__e-hyy*U~~U*Q䑑h!#3Ә\//bhw53#5!b//xh/"&54654&>54&54633#"33^[ ?;;? [^=436'44'6348M7X2#4$/^4M8/(!+[/13  313T. )/ch/5326654&54675&&54654&&##532"#c336&44&633=^Z ?;;? Z^/) .T313  31/[+!(/8M4^/$4#2X7M8c`3cHJfQ3Jc`3JHfQ33JJJH0HTo,7'7'7737'*l 0 l*xoF.77.F 5'37' FP;GG75'75'37'7' FPGGGG[3C"&'732654.5467&&54632&&#"6654.'7\ 2=*)-)@H@)3(LK2Q(9#*&)@I@)2)Z)@H #(@H %@&!-)%)>.,A(4N"5%%*>.0<';N!+ &"", )H %"&&5466333>Fp@>jC+6Q.`KO])R &ȕk]'zy;%?K7&>54&#"'6632"&546327&>54&#"'6632"&54632f"&$%')D*>L'&++++"&$%')D*>L'&++++*C746!!.1!"K9*B76>'*$#))#$**C746!!.1!"K9*B76>'*$#))#$*W;%+7%&>54&#"'6632"&54632%'3"&54632~"&$%')D*>L'&++++ P ++++*C746!!.1!"K9*B76>'*$#))#$*X^^*$#))#$*%+77&>54&#"'6632"&546327'3"&54632f"&$%')D*>L'&++++ P ++++*C746!!.1!"K9*B76>'*$#))#$*X^^*$#))#$*^)7''3>54&#"'6632"&54632 F0"?=)F0#f:;W1%55 ))))LLk,6'-< ,&.)F./B0,4$)""))"")t<)%#773267#"&&54>'72#"&546Z F0"?=)F0#e;:X1%55 ))**LLk-6'-< ,&.)G-/B0,4$)""))"")3!#/xbw!#5!5/I~33BV[/bw~533bBV/,h !#3%3#<++\///bh 53#5!'3#b<_++///!#/bw#5!5r/_h33BӘ/bhw533bB/R:;"&&546632'26654&&#"7"&&546632&&#"3267,L{GG{LMzGGzMCe88eCCe88eK-I,.L+#2".86,&5 RffPPffR*IWXHHXWI^/Y>:U.'K;BM*:*3"&&546632'26654&&#"'32##532654&##,L{GG{LMzGGzMCe88eCCe88e(r9OP81''*+&' RffPPffR*IWXHHXWIjk8=BAs&)$ p?-6"&&546632'26654&&#"'532#'#532654&##,4U33U44U33U4*C''C**C((CL /..#)?2Y:;X22X;:Y2%(I//I))I//I(=$SFFfnD#53#333773#57##'#[``G-,G7G*Hn666rPPrʉiibD&:"&'73254&''&&54632&&#"733773#57##'#}!6!%1.%9/2#. :tG-,G7G*Hb%'  '#'1'   '##8 6rPPrʉii1p"{,5"&&546632#'##"&546754&&#"3267275UOPNREZ,2G'5LA5&- $9 (:+/E% "0)?00H)$,1<<<<<<<<<<<^<<l^<]<g <C "&54632'2654&#",HWWHHWWH+66++66ldbllbdl3NONMMNONO 535#566733{i)54r6)6O'>54&#"'66323C[/.'1&K+>N+J0%9P>&, ##)A>%CH-6C&"&'732654#52654&#"'6632)3Q*9!$4;9+%0&D+7P'(+3(C*"!$!F()"""81#.2&$4O53533##5/::::I! tt.hhC"&'732654&#"'73#632+7N*(G'36*%  (9QU*"!:1%(.8`C@9:,$#,i[Ja/, HK)E8%<#O >7#5!6)%18Dmf87$>nrDC%2"&54675&&54632'6654&#"2654&&'+GM-'!#H<>H(*(O-)#"&6).3",?,&7'.98/"-0%.?# ' ))C %73267&&#""&'73267#"&546632+*.6)#.>%3&0C,@?E%?(JX0Q^#-:;- - GK(E7&<#i\Ia/".5467X&02:-5&'4,RZ9T|A>wBAw?l"'6654&'7.5&&5.92/?wABw>A|T9ZRD] "&54632,g'66'#"&54632#5' &&%-E= "&54632'2654&#",=NN==NN= .. .. XNNUUNNX2::<66<::a1!5#56673"R!)2* =356654&#"'66323NS&';$6>G2$;N! !#52(L-5=$"&'732654#52654&#"'6632+"D 1#`)((>"/;8 'F '3&&,(7',1=7573533##5q.ad9229Jaa*JJ1"&'732654&#"'73#632-)= -%$  2>G ' 6F 4//;= #%"32654&"&54632&&#"66327(#,:OVD, +3-34A#&"RFV[) ;95*+=1 3>7#53* *-4RM)5$.SW5=%0"&54675&&54632'6654&#"2654&',8E( D.2A!%H!, )5"/' 5# % %//%!  %!%3  %= $73267&&#""&'73267#"&54632#,(-)3-33A2;NV'#( 995*,:3<("&546632&&#"3267ZF_0M-#2 !/=;/)2YO6L') @54@ ))b"&546632'53#'#'275&&#"?L)B'+@56,'&'5.XP5K)7|)$5(>57="3&&"&&546632#32678$=20P//K*HMF./6+-/)(K54L)SD 24 ("i#5754632&#"3#OOAE/-!&)%0;G/ *#2*6F%"&5475&&5475&&546323##"'3322654&#"2654&##"&'*FO5 'M5 R I5?G@>cV(((($5@%#; 4,+(" *6>0 5: "$)/B!%! (( !%%  b36632#54&#"@8$85@$(ׁE!A>)(g#53"&54632<%2|g7"&'73265#53"&54632.!!/ =1 /+(2'?$ b 3373#'@H}GkFʠCTb"&5#53327}53Q #<883  1F 3366326632#54&#"#54&#"F21 E5!5/>#!,>#",A-<$F8&,/&,/336632#54&#"57%85@$(A0!A>)("&&546632'2654&#",*H,,H*+G,,G++11++11(K56L''L65K(4@45@@54@ 336632#"&'72654&#"46AD)B&.N(4'.*)$YK7M)7j>:3<57#"&546632373'275&&#"v4?L)B'-4,'&'5.o8XP5K):(>57=336632&&#"6B'# =AK', 6(2'"&'732654&'.54632&&#"4+L7%(&8 7%G@$?-%"4 9%I) #(5(  $(90"&55#57733#3267qH8MP5#, 1J=0dd2)+/ "&553326753#'# 74@#)@49A=('2! 3366773zB>>>wA004337733773#''#Y@,082+;WK*,A[[[[[[7'3366773#'&&'#ofD+&DhoE/  +B  BE E"&'7326773366773  & @E <><2$@//2A 57#5!3ս!2!2 "'7"3&&"&&546632#3267Ip-f4$=20P//K*HMF./6n)x{+-/)(K54L)SD 24 (" "'7"3&&"&&546632#3267'"f-`$=20P//K*HMF./6x)+-/)(K54L)SD 24 ("2"3&&"&5467#"&&546632#326732678$=2%* 0P//K*HMF./.%  +-/)R!*(K54L)SD 24 (/  "&54673&&#"'6632'267#*IS?-/>$G_,G,$77XD 11 (YP4L*2./1,g4632&&#"6632#54&#";?# "8$85@$(Z;G0*#Q!A>ļ)($%"&54673366773'2654'#-'*rA;;?q)'  +$0"&&"1$+* "/* g5&&546632&&#"2H+G)/D"/ +5<= M:*:$(*%)B "&546632373#'#'275&&#"?L)B'.456.%(%6/XP5K)$5(>57=*%"&'732677#"&546632373'275&&#"A4--3?L*C%-5QB,'(&60,+$8WJ3I(=C*<23;g 535#533"&54632r|222]'<zG53ޜ//E5!**=E5!=**:SA)7'7&5467'76327'#"'72654&#"f,T$S,W0?>1W,T$T,X/?>1o1EE11EES-U1C#;V-Z%%Z-V1D";U-Y&&J<.HQH.YI<7J,"?22<.HRH.aO<7eq9)1&) ';+?Q+0-&%)=.@W,M(356654&'#57&&54632&&#"3#!N>>uc s_>U0;*AF $$H2`8 4 >Uc+ /A4< 84GG5#~!5#535#5333667733#3#U\!"\R0A/@!C##C!/A0:61"&'#57&45447#576632&&#"!!!#3267vb@;;@j3X1<&I[&XE+A1%] u,,v-!/!bV1  1Ua%",+2q"5&&5466753&&'667:Yp5\83,@(. 4$H'@87A!h {jEe<jg"44"gWCX O X1&"&'732677#57376632&&#"3#*4- hF) PT1 !*&Ga >PL;8dh >%;"??=\4`"/5""&7&&5467722327&'667'7&'m <>=Ip_ 0   0 +!1:21 N2 0  S<67;H R{%lk\iq$/ ",%0d[ nHN635665445#573&&'#57&&54632&&#"3#3#!N>>|W ^Ms_>U0;*AF $$H2`8,!.!Uc+ /A4 1!14GG.(~#'+3'5#575#57533533#3##'#73'#'3'#3'# ;@5KKKKT^sAIIIIT]t :bLJa3+D+0D0J0DDD*G~3#575323###3&&#327#]]4-.C9vznb[7P,S"1CC,S.;D2=F11*H~'-23#575#575323#3###4&'#366'3&&#327#]]]]MrXNMWtMFG3;;k#t(:(t5?. .@? : ; FT#5.546753&&#"32675#537Cf:|g<.O1<&W_]S :tCXndR`ec,.!y{E> d=:"&5467#573667#5736654&#"'66323#3!3267CZo PE.-F!8/)6,!N=5Q.a3>;-I!&$d XO(+ ,.&4!/%.(G/-1 0)+6) 7%/`""5.546753&&'667JEj;j5/O13 "71!P2NGHMncRaa`+/#,&0dp  l ~753267!573&&##5!#3##'lOS`L ]LOEJH]J]C:<,.&D1H1LX-~"'75'75377>54&'7]s]sT«%NB(Ed ++5H+*6ǞQ+[HQ+[)=' To57!~!5'75'75#5!#77ˊA+KHA+K@@@(MH@(L7!~ !#57!#5!R,0&M11*1~!35#575#5732##!!32654&##ttttBh<=hA^TMTTMT,C,6$N>@P&C1HABC7E~35#57!!3#3#OO|4GFx8| <p7'77'7M1!!1 -- <ph <ph=' zM&h 0? '3?K"&54632'2654&#"'%"&54632'2654&#""&54632'2654&#"4AA44AA4##$$f4AA44AA4##$$*4AA44AA4##$$F>=DD=>F*,.-**-.,:0F>=DD=>F*,.-)*,.,*F>=DD=>F*,.-)*,.,?~' sM&h<~' sM&h U' sM&h<~' sM&h <' sM&h <~' sM&h<' sM&h<' sM&h<'sM&h<~' sM&h<~'sM&h<~' sM&h<~' sM&h<' sM&h<~'sM&h<~'sM&h<~' sM&hS?~ !-5#56673'%5#56673"&54632'2654&#"R!)2mfR!)24AA44AA4##$$* {:<* F>=DD=>F*,.-)*,.,<' zM&h Uh, %5#53533# Bh>>U+i5!U+>>f~ 7'7'77',,,,~----U`3 "&54632"&54632'5!,>>yU&kUT@'&)x0h%%5%u-0>Ok0h75%5%5k-u0OO>U 35!5%5%UR҇>>JGI,,IU 35!%5775''5UR҇>>GI,,IGJU, %5#53533#5! B>>>>o 3#''#oHHB11B~UAS77#537#5!733#3!pLg[ L=Lg[LA>>>>L ".#"'66323267/)')5H&/)')5H""4G6""4F6L &kUhi%5!5!h>Uhi7!!Uh>`h:7546632#54&#"`5\;;\5AL??LhAa55aAMTTMUh,73!UBlhz>\'3%"&'##"&&5463236632%27&&#"2654&#"7O&)5#$=%U=2DO6-E(W@(4$+/R,15/#=!>:=-)F+NY<)5@,M2TfSX1+-)(6=+0?17=2"&&54632'2654&#",!9#K2"9##9""**"!**:&;F 9(&:..#%..%#.h3Q"d&XW''3!"QdTE'L  *73267&&#""&&5466326454&#"'6632C-AY!F!IIh0S34bC)OKA9& P.asCw;Fmc*"Y.W;Bf:&"}p4 #p_b#"'732654.546632&&#" *  <9  )  ;>RN7~7Ag<>UM6~~8Ah< p#46632&&#"TK<9  )pAg<>UMbT"'732653 *K<>RN_Ah<>G4'736673/Gt<_ -;  m+-a&2u 8#33736677#8^X>? !p9m7dd7mF 35!5!5!5!5!FLGGFpOC R'tOOF%~ 55!!!Fwx5FF5GG4$~!#!4Ux S=".:"&546632&&#"3267'77'7"&54632'2654&#";P)B% . $1.%% 6v1!!1=NN==NN= .. ..AVN4J'' @33? '--XNNUUNNX2::<66<::t '6654&#""&''66746323267;C!)O9Ih\5%+!C;F2*CP[4 tePK^NM<3(>1".54>32!"32673!2554'&&#",9cK++Kc99cK+b6T5_"&(r G&(H 4\zFFz\44\zF <=3V7 %%77706 >7? 60g7 7'%j? 607|6/ ?95!!!!!+p]hCCp  .g6>>6g!77'3'#'##O.  .g6>>6**oCCh]F'7!5!75'!5!'75*oCCh]o*.g6>>6g.!7733737*.g6>>6g.*o\iCCo*%d%'7!'57!'7d-~T~--~~-&&&&U0#'7'73'7.&&&&9.~~--~[~.^6%"&&546632'26654&&#",Ek>>kEEk>>kE4R//R44R//R^>kCCk>>kCCk>20T66T00T66T0Wu7!WuVIg-7!%!!Io\g:1dIg- 77!%!!I;3Xg1q7(]!K7b% ,  K  >iX753>i>iX753%!>oFi,[>m.H73>m>m.H737%%>,YmM>UD%5!+U>UD%5!'!+Uh[*mH%%5%3m%*mH%%5%3'/m%MAmqH73YmmCH%%5%3@Ym%Dd0#7!'26654&&#"7"&&546632DCf;;fCBg;;gB1N,,N12M,,Md4;g@Af;;fA@g;1.P34O..O43P.3[%R/%"&&546632'26654&&#"7"&&546632,DqDDqDDqDDqD4Y88Y43Z88Z3%@''@%%@''@[=qNMq==qMNq=20Z@@Z00Z@@Z0:#A,+@$$@+,A#q 7!%!!=M4 v3=+4 7!667%!&&'73667!=66)4Cp#VE+8%= jA' v3#=2*=+^ M@&:~?nab&'73>7;\8)D$rN6Ou&&>CwM2IM!"&5466323'6654&'(=(G."2 D. #A<0N'%5! 0[9'E )/Ti7J&Q!"&546632%#"&546632h(<&D,"z.L-(;%D,".L'%5!<7J%'%5!k*|7J& O#.5463236632.Zr>T=1JK0>S>r ayj6bd5CC5db6jy O47"&546327&&5466326632#"&'#!5>7#;JS:"2'C))C'2";RI<%G /F,z,F0 FUCFG -O%8 8%O- GFCU&1KV((((VK1&S#53.%% om O#%#"&54>73#"&'#!5>7F)7J@qUVp@I8)E /F,z,F0 4&BF-Q]{XX{]Q-FB&4KV((((VK 'Om+7EMU%"&&546632'26654&&#""&546323"&54632"&'73267'254#"3254#",UKKUUKKUGl==lGGl==lfBQ"?,,@ "R 'KTUKKUTK->oIIo>>oIIo>$##$$##$E= '$$' =E;;Y'5AM%"&&5466322654&#"32654&#"267'#"&''"&546323"&54632,P{DD{PQzDDz:DQ "@..@" Q    ;F{NOzFFzON{F$$$$$$$$C> '&&' >C  %#.5463236632.HSRC)oVBWWBVo)CRSH /@23CaGbg;JJ;gbGaC32@'m$8DPY&&#"3262672654&#""&&54632#32654&#""&'663266726+<  <=cTQ:;zqpz;jEU~Ey:E3U3#p"  "Y]crWXrbt .    28P6.@GQWKwF)S^cPJ ED2M*:6| k,(/78.(,L8!\#*8F%"&&547&5467&&54>7'267!'66327&&#"66327&&#",j@[$>/ *0/ />$[@j>KKZ! ! "@;_?6;  'O ;6?_;@_9::9##A77A##A77'rm %;IW%"&54632'"&5463226654&#""&'&5467663266327&&#"66327&&#",a`hYYh_bDm?oo?mDY"?mn?"  # #  # #  m*6SMMS6*9v[zhhz[v9-VS &%b__b%& SV%!!A77A!!A77-+X!*'73546323%37'6654&#"354&#"U((.YPPY.((,,1##1I2332F$$W``W$$ )#00#) $;CC;<*26654&&#"5#535.5466323#,1N--N11O--O<^5>mEEm>5]=+-P34N--N43P->e?c e)726654&&#""&&54663275%#71N..N11O--O1El??lE%A;:>lB-O43O--O34O-9=jBBi=:?[Bj=[} 8%2654&#"'7&&'#53667'76675373#'#5&&',;MM;;MM+X ll V+W+@*Y+XllW+X%/@*M==MM==Mm,W+>)X,X tt W,V$0>.%Y,Ztt `3'377''#L(@AA@@AA SRE1' 33%!''#1HPjaRRah3<}}h^|^= 526548:<<:[]]22,-21ODDOv= &546"3v[]][:<<:ODDO12-,2;5&&546632&&#"2H+G)/D"/ +5<=[!L:+:$(*%)B v373'3] ]g]]WW'3']]W%"&'573267I3i  +5+?<36 + 8l 8 8>_3f?Y8 8l _B38@ALY; 98Ln z24 5# ".9EQ\gs"&54632'"&546323"&54632%"&54632!"&54632%"&54632!"&54632%"&54632!"&54632%"&54632"&54632'"&54632+z    `P  d  M  { &R$mn&%R8l '7A:88mc'7I/s7.M'7CU'.8 '7+:8)8c'7$/*7 /'7B9/U/ 8'73'##rRr#v8 qF'73'#$iVi$nqq]A".#"'66323267t&7/4& 7/A",#;M"-":M{I".#"'6632327w)86-)(86" 9BB:AY5! Y995! 99Y;"&&'732667,6B!3, !+3"B;-E%00%E-<"&&'73267,8DD&12&D C<*E&+>>+&E*J "&'73267,FF2/++/2FM4#11#4ME"&&'73267,7AH#**$H@$;!#33#!;$Ln "&54632,&&&&L####g; "&54632,""""  L "&546323"&54632L !! !! 0 "&546323"&54632<| '6654'7  SDKD<(+61,++{h '6654'7  S AIC&'0)&+*;-"&&'732667'"&54632,6E#00""00#D7  ;-E%2 2%E- "&'73267'"&54632,HJ.5..6.KHM4%33%4Mt9 "&54632'2654&#",4::44::4!!!!98()77)(8%"!!"p "&54632'2654&#",*77*)88)2()22)(2$8'7'7.W:4.W:8l'7'7+\96+]8  >'737r#vv#r> qq M'737i$nn$iq\\q$I03J$ Qk8'7'7c:Wic:W8jl'7'7j8]uj9\  8'>32.#"3!B66B"3+! ,8%E--E%//I '6632&&#"2FFFF2/++/5LL5#11)a"&54676632/ +/ )'$%?"$>p &&5467L+EKDS >)+-06+)c'665#"&54632   +)"%'$%?<|5#5353Sss5H/Hx533#5ssH/H=5#53Oo=^/# '654&'7+T@ W)L &?Bj &546"3jEEEE&''&3-.4$  -53533Y6Y/jj/5#53#YYj//j 5#53533#YY6YYH/HH/Hj53//)n 0 z '6654&'7?.$#A4U(&$"+,? &&5467SA4VO?.%"?#",,)z'6654&'73?."+(6#&U(`H +,z'6654&'73?."+(6#&U(`H +,"&54667332678+;':%-$ 0./2(;! '"&5466733267:,;'=%," --.3(> == >599::99:A{I 7"5533267XM@  \/  1?U5!ګ::fX '6632&&#"ed_mmX*>AA>*:55LL "&546323"&54632''7{#R1Lus" "&546323"&54632''7|%_5lw$4 "&5463277"&5463251DKsS LL "&546323"&54632''7m`1RLui"s "&546323"&54632''7zo5_lm$w3 "&54632'77"&54632]@B)IS L& -"&546323"&54632'"&&#"'66323267-#+$**&#+$**Lw'5'5L "&546323"&54632'5! L// "&546323"&54632%5! ..LH "&546323"&54632''737^``^L\II\ "&546323"&54632''737c!dd!c|`KK`: '73'#'7dDdg#W1:"\\"Hx" x '73'#'7"]H]"]{a#ZZE ]'5: '73'#'7dDdgq0d:"\\"Hp$uYx '73'#'7"]H]"]wZ#UZZEX%_:'73'#'6654&'7dDdgv  %;?::"\\"H#)%#(#'73'#'6654&'7"]H]"]u !& x8ZZE#*D&#:#'73'#7"&&#"'66323267dDdgC*$+!#*#+!:"XX"EG'2&3'73'#7"&&#"'66323267"]H]"]D *!-%( *"-$WWBJ&5'5;@"&&'732667''7,6B!0.!"-0"B;'X4;-E%2 2%E-l|( "&'73267''7,FF/1,,1/FC)_5M4%33%4Mbt$;@"&&'732667''7,6B!0.!"-0"B1e4X;-E%2 2%E-lq(| "&'73267''7,FF/1,,1/FIk5_M4%33%4Mbm$t;P"&&'732667''6654&'7,6B!0.!"-0"BQ#)=D>;-E%2 2%E-o$2)((& "&'73267''6654&'7,FF/1,,1/F] !%;>9M4%33%4M_#*$#&#;"%"&&'732677"&&#"'66323267,1=//././=*$/#%*#/#; 2++2 &2&2 #"&'73267'"&&#"'66323267,FD......D *!-%( *"-$@****@'5&5:$'73'#7"&'73267_D_`>;&(**(&;:SS>I8!   !8'73'#7"&'73267!\H\!]BB.++,*.CWWEI9%""%9YK5!''7 &Y99h'c15!''7 y'99\&g0>- "&54632'737,  Arzzrss "&54632'737,Alyyl5sm\\m/ .54677-G:I3+JCA&)*3'./ .5467'7-G:Is@K&A&)*3'82' #&&5467'66323267#"&&#"G$:@:% #%*#/#%*$2"' |&2&2/ '6654'7'7 I;F-2*JA&'3*)& / '6654'7'7 I;F-?J'A&'3*)&2'#"&&#"'66323267'6654&'7m*$/#%*#/# %;?:&2&2! '"S5!'NNz'5!'ޜpS3Npxpz3ޜpx!7S 53!53!53NNNNNN!7z %53!53!53ޜSA 333NNNNN7 p p zA 333ޜ7 p p ES 53!53!53!53ppppNNNNNNNNEz %53!53!53!53ppppޜS_ 53535353NNNNNNN~z_ 53535353ޜ~pS!#!Nzkpz%!#!Nz pS!#!kpz%!#! pSS#!5!SNzpNpSz#!5!SNzpnpzS#!5!zpNpzz#!5!zpn!3!N,k%!3!N, 3!ޜkN73!ޜ S!5!3S,NNS%!5!3S,Nޜnz5!3'Nz'5!3'ޜnp!#3!NN,kxkp%!#3!NN,xp !##3!N'kkp !#33!'N,kkp!#3!kxkp %!##3!N'n p %!#33!'N, np%!#3!xpS#!5!3SN,NpNpS#!5!3SN,Npnnpz #!5!3#SN'pNpz #!5!33z,N'pNkpz#!5!3zpNpz #!5!3#SN'pnnpz #!5!33z,N'pnnpz#!5!3zpnnpS!#!5!NkNpz #!5!!!SNz,pn'Npz %!#!5!5!N,zN'pz%!#!5!NnpS!#!5!kNpz !#!5!!kn'pz %!#!5!5!N'pz%!#!5!n!5!3!Z,N,Nk !!5!3!,N,'nk %!5!5!3!,N,'N%!5!3!Z,N,ޜn!5!3!ZNk '5!3!!'ޜnkN' 75!5!3!'N%!5!3!Zޜnp !#!5!3!N,N,kNkp !#!5!3!N,N,knnkp %!#!5!3!N,N,Np %!#!5!3!N,N,nnp !#!5!3!NkNkp !#!5!3!,N,kNkp !#!5!3!kNkp %##!5!3!!z'NnnkNp %!##5!5!3!N'n'Np #!5!33!!z,N'pnn'Np %!#!5!533!'N,N'np %!#!5!3!Nnnp %!#!5!3!,N,nnp !#!5!3!knnkp %!#!5!3!Np %!#!5!3!nnK S53!53w>NNNNK z%53!53w>ޜjS33NNN,,jz33ޜ,,5!5!'ZSNNNNp3#3SNNpxxp %!#!!!Nz,1NNpS ##!#SNNpkNkp !#!##!NN,S1pS #!5!5!5!SN,zpGNNNpS ###5!SNNpkNp #!5!##5!NȜN,pNGN %3!!!N,,1NNN 3333NNNkkN 333!SN8NzSN1NS %!5!5!5!3S,,NNNNG !533338NNNNk !533!5!3N8zNSNGNp %!#3!!!NN,,xNNp 3##33NzNNpxkxkp 333##!NNNN,pxNpS #!5!5!5!3SN,,NpGNNNGp 3###533SNNNpxNp 3!533##5!SNNN,pxNGGNp 5!!#!5!'NSNNGNpS ###5!#SNNpkNNkp 5!##!##5!'N,N,SNNkGN !5!3!5!Z,N,ZSNGNN !533333ZNNNNkk 33!!5335!SNNSNNGNNp%!#!5!5!5!3!!!N,,N,,GNNNGNNp###533333#SNNNNNpkNkkNkp 33!!533##!##5!SNNzN,N,SNNGkGNpS4>33#"5]{F''HwFpF{]5NGvHppSS!#4&&##532SNGvH''F{]5pHvGN5]{S##532665S5]{F''HvGpF{]5NFwH333#".NFwH''F{]5XpHwFN5]{X3#-++YWX#5+-+WYWX #5533-+++WWWWSS5!'zNNS3NS5!zNNpSS3NpSz'5!'zޜz3ޜz%5!zޜpzS3ޜpz%!5!5!5!,z'N'pz#333z'N'pkz!!5!!z,''pz###3z'N'k,X!X,DpX5!XppX!Xp^pX}!Xp pX,!XpDpX!XpkpX!XppX9!Xp7pX!Xpxp ! pxp!pxpw!wpxp,!,pxp3pxp3pxpK3Kpx,pX!,,px*X #/;GS_kw+7CO[gs4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&8      8      8      8      8      8      8      U      ZU      ZU      ZU      ZU      ZU      ZU      *L* #/;GS_kw+7CO[gs4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&    >    >    >    >    >    >    >   NU   NU   NU   NU   NU   NU   N*:E #/;GS_kw+7CO[gs4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&4632#"&'4632#"&'4632#"&/""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    /""//""//""//""//""//""/G    "//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   N"//""//""//""//""//""//B   9X5!X9 pX3 Kpxp,,!,pD,pX,!,,pD,,!,,DpX!!,,pxDDpX!!,,,DDDpX!!!XX,DxpX!!!XXp,,X!,,,DpX!!,,,,DDDpX!!!X,,pMQ4 %3#5754632&#"3#33"&54632vBBEI*EggR(&&&&>MJW ? ^MC]L####9%"&533267%#5754632&#"3#.)R  BBEI*Dgg 95f> >MJW ? ^MC]cd$#4>55#7#3Q"8DC8"tu"8CD8"QQDY;+)5Oyװ"Ǽ-+XXX(lc'7*1190--0e ee_.91]]0Hf  $ < H T `l&~ & * 6 D*:n2$D*    L  dP *  4 4 2  8 4X           $   >  , ^  0   .   2  8  & R < x  "  .  2   "   0 J d ~0  (  ,  4  8 J< 0 H " 2 68 J a gi & l   J    1  []   [0]  [-]  [*]     [$]  [-,*] ,  a ,  g,  1 ,  J 2010 - 2020 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name Source .Source Code ProRegular2.038;ADBO;SourceCodePro-Regular;ADOBEVersion 2.038;hotconv 1.0.116;makeotfexe 2.5.65601SourceCodePro-RegularSource is a trademark of Adobe Systems Incorporated in the United States and/or other countries.Adobe Systems IncorporatedPaul D. Hunt, Teo Tuominenhttp://www.adobe.com/typeThis Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: http://scripts.sil.org/OFL. This Font Software is distributed on an AS IS  BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the SIL Open Font License for the specific language, permissions and limitations governing your use of this Font Software.http://scripts.sil.org/OFLsimple asimple gserifed i & lSami Jcursive cursive cursive Serbian Cyrillic breve []slashed zero [0]typographic hyphen [-]typographic asterisk [*]slashed dollar sign [$]alternate numeral one [1]typographic alternates [-,*]simple a, cursive simple g, cursive , Serbian 1Sami J, cursive ?@>AB>9 0?@>AB>9 gV 8  A 70A5G:0<8A00<A:89 JA:>@>?8A=K9 A:>@>?8A=K9 A:>@>?8A=K9 A5@1A:89 1:8@8;;8G5A:0O :@0B:0 []70G5@:=CBK9 =>;L [0]B8?>3@0DA:89 45D8A [-]B8?>3@0DA:0O 72574>G:0 [*]70G5@:=CBK9 7=0: 4>;;0@0 [$]B8?>3@0DA:85 70<5AB8B5;8 [-,*]?@>AB>9 0, A:>@>?8A=K9 A5@1A:89 1, ?@>AB>9 g, A:>@>?8A=K9 A00<A:89 J, A:>@>?8A=K9 2 $%&'()*+,-./0123456789:;<=DEFGHIJKLMNOPQRSTUVWXYZ[\]bc     de !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRfSTUVgWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~hjikmlnoqprsutvwxzy{}|      !"#$%&~'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ "      B >@^`_?  !"#$%&'(#)*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !AaC      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-.AmacronAbreve Aringacuteuni01CDAogonekuni1EA0uni1EA2uni1EA4uni1EA6uni1EA8uni1EAAuni1EACuni1EAEuni1EB0uni1EB2uni1EB4uni1EB6AEacuteuni01E2uni0243uni1E06 Ccircumflex CdotaccentDcaronuni1E0Cuni1E0Euni1E10Dcroatuni018AEcaronEmacronEbreve EdotaccentEogonekuni1EB8uni1EBAuni1EBCuni1EBEuni1EC0uni1EC2uni1EC4uni1EC6uni1E16uni01F4 Gcircumflex Gdotaccentuni0122Gcaronuni1E20 uni00470303uni0193 Hcircumflexuni1E26uni1E24uni1E28uni1E2AHbarItildeImacronuni01CFIogonekuni1EC8uni1ECAIbreve Jcircumflexuni0136uni1E32uni1E34LacuteLcaronuni013Buni1E36uni1E38uni1E3ALdotuni1E3Euni1E40uni1E42Nacuteuni01F8Ncaronuni0145uni1E44uni1E46uni1E48Omacron OhungarumlautObreveuni01D1uni01EAuni1ECCuni1ECEuni1ED0uni1ED2uni1ED4uni1ED6uni1ED8Ohornuni1EDAuni1EDCuni1EDEuni1EE0uni1EE2uni1E52 OslashacuteRacuteRcaronuni1E58uni0156uni1E5Auni1E5Cuni1E5ESacute Scircumflexuni1E66uni015Euni0218uni1E60uni1E62uni1E9ETcaronuni0162uni021Auni1E6Cuni1E6ETbarUtildeUmacronUbreveUring Uhungarumlautuni01D3Uogonekuni01D5uni01D7uni01D9uni01DBuni1EE4uni1EE6Uhornuni1EE8uni1EEAuni1EECuni1EEEuni1EF0uni1E7EWgraveWacute Wcircumflex WdieresisYgrave Ycircumflexuni1E8Euni1EF4uni1EF6uni1EF8Zacute Zdotaccentuni1E90uni1E92uni1E94uni018FEngIJuni004C00B7004C uni01320301amacronabreve aringacuteuni01CEaogonekuni1EA1uni1EA3uni1EA5uni1EA7uni1EA9uni1EABuni1EADuni1EAFuni1EB1uni1EB3uni1EB5uni1EB7aeacuteuni01E3uni0180uni1E07 ccircumflex cdotaccentdcaronuni1E0Duni1E0Funi1E11ecaronemacronebreveeogonek edotaccentuni1EB9uni1EBBuni1EBDuni1EBFuni1EC1uni1EC3uni1EC5uni1EC7uni1E17uni01F5 gcircumflex gdotaccentuni0123gcaronuni1E21 uni00670303 hcircumflexuni1E27uni1E25uni1E96uni1E29uni1E2Bhbaritildeimacronuni01D0iogonekuni1EC9uni1ECBibreve jcircumflexuni0137uni1E33uni1E35 kgreenlandiclacutelcaronuni013Cuni1E37uni1E39uni1E3Bldotuni1E3Funi1E41uni1E43nacuteuni01F9ncaronuni0146uni1E45uni1E47uni1E49 napostropheomacron ohungarumlautuni01D2uni01EBuni1ECDuni1ECFuni1ED1uni1ED3uni1ED5uni1ED7uni1ED9obreveuni1E53ohornuni1EDBuni1EDDuni1EDFuni1EE1uni1EE3 oslashacuteracuteuni0157rcaronuni1E59uni1E5Buni1E5Duni1E5Fsacute scircumflexuni1E67uni015Funi0219uni1E61uni1E63longstcaronuni0163uni021Buni1E6Duni1E6Funi1E97tbarutildeumacronubreveuring uhungarumlautuni01D4uogonekuni01D6uni01D8uni01DAuni01DCuni1EE5uni1EE7uhornuni1EE9uni1EEBuni1EEDuni1EEFuni1EF1uni1E7Fwgravewacute wcircumflex wdieresisygrave ycircumflexuni1E8Funi1EF5uni1EF7uni1EF9zacute zdotaccentuni1E91uni1E93uni1E95enguni0237ijuni006C00B7006C uni01330301uni0250uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0251uni0299uni0259uni025Auni025Buni025Cuni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni029Cuni0268uni026Auni029Duni029Euni026Buni026Cuni026Duni026Euni029Funi026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0278uni0279uni027Auni027Buni027Duni027Euni0280uni0281uni0282uni0283uni0284uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni02A4uni02A6uni02A7uni0294uni0295uni02A1uni02A2uni01C2uni0298 uni014A.aa.aagrave.aaacute.a acircumflex.aatilde.a adieresis.a amacron.aabreve.aaring.a aringacute.a uni01CE.a uni1EA1.a uni1EA3.a uni1EA5.a uni1EA7.a uni1EA9.a uni1EAB.a uni1EAD.a uni1EAF.a uni1EB1.a uni1EB3.a uni1EB5.a uni1EB7.a aogonek.ag.a uni01F5.a gcircumflex.agbreve.a gdotaccent.a uni0123.agcaron.a uni1E21.a uni00670303.ai.a dotlessi.aigrave.aiacute.a icircumflex.aitilde.a idieresis.a imacron.a uni01D0.a iogonek.a uni1EC9.a uni1ECB.a uni012D.a uni0268.a iogonek.d iogonek.da uni0268.d uni0268.da uni029D.dl.alacute.alcaron.a uni013C.a uni1E37.a uni1E39.a uni1E3B.alslash.aldot.auni006C00B7006C.a uni026B.a uni026C.aAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9 Alphatonos EpsilontonosEtatonos Iotatonos Iotadieresis Omicrontonos UpsilontonosUpsilondieresis Omegatonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigmatauupsilonphichipsiomegauni03C2uni03D0uni03D1uni03D5phi.a alphatonos epsilontonosetatonos iotatonos iotadieresis omicrontonos upsilontonosupsilondieresis omegatonosiotadieresistonosupsilondieresistonosuni03D7uni03D9uni03DBuni03DDuni03E1uni037E anoteleia anoteleia.capuni0374uni0375tonos tonos.cap dieresistonosuni037Auni1FBEuni1FBDuni1FBFuni1FFEuni1FEFuni1FFDuni1FCDuni1FDDuni1FCEuni1FDEuni1FCFuni1FDFuni1FC0uni1FEDuni1FEEuni1FC1 uni1FBD.cap uni1FFE.cap uni1FEF.cap uni1FFD.cap uni1FCD.cap uni1FDD.cap uni1FCE.cap uni1FDE.cap uni1FCF.cap uni1FDF.capuni0410uni0411uni0412uni0413uni0414uni0415uni0416uni0417uni0418uni0419uni041Auni041Buni041Cuni041Duni041Euni041Funi0420uni0421uni0422uni0423uni0424uni0425uni0426uni0427uni0428uni0429uni042Auni042Buni042Cuni042Duni042Euni042Funi0400uni0401uni0402uni0403uni0404uni0405uni0406uni0407uni0408uni0409uni040Auni040Buni040Cuni040Duni040Euni040Funi0462uni0472uni0474uni0490uni0492uni0496uni0498uni049Auni04A0uni04A2uni04AAuni04AEuni04B0uni04B2uni04B6uni04BAuni04C0uni04C1uni04D0uni04D4uni04D6uni04D8uni04E2uni04E6uni04E8uni04EEuni04F2uni0430uni0431uni0432uni0433uni0434uni0435uni0436uni0437uni0438uni0439uni043Auni043Buni043Cuni043Duni043Euni043Funi0440uni0441uni0442uni0443uni0444uni0445uni0446uni0447uni0448uni0449uni044Auni044Buni044Cuni044Duni044Euni044Funi0450uni0451uni0452uni0453uni0454uni0455uni0456uni0457uni0458uni0459uni045Auni045Buni045Cuni045Duni045Euni045Funi0463uni0473uni0475uni0491uni0493uni0497uni0499uni049Buni04A1uni04A3uni04ABuni04AFuni04B1uni04B3uni04B7uni04BBuni04C2uni04CFuni04D1uni04D5uni04D7uni04D9uni04E3uni04E7uni04E9uni04EFuni04F3 uni0430.a uni04D1.a uni0431.srb uni0456.a uni0457.a uni04CF.auni2116zero.aone.a zero.onumone.onumtwo.onum three.onum four.onum five.onumsix.onum seven.onum eight.onum nine.onumzero.bone.bzero.capone.captwo.cap three.capfour.capfive.capsix.cap seven.cap eight.capnine.capzero.cone.c quotereverseduni00ADuni2010 figuredashuni2015uni25E6uni25AAuni25ABuni25B4uni25B5uni25B8uni25B9uni25BEuni25BFuni25C2uni25C3 invbullet filledrect underscoredbluni203Euni203Funi2016 exclamdbluni2047uni2049uni2048uni203Duni2E18uni231Cuni231Duni231Euni231Funi27E6uni27E7uni2E22uni2E23uni2E24uni2E25uni2117uni2120at.case asterisk.ahyphen.a uni00AD.a uni2010.adollar.a zero.supsone.supstwo.sups three.sups four.sups five.supssix.sups seven.sups eight.sups nine.supsparenleft.supsparenright.sups period.sups comma.sups zero.subsone.substwo.subs three.subs four.subs five.subssix.subs seven.subs eight.subs nine.subsparenleft.subsparenright.subs period.subs comma.subs zero.dnomone.dnomtwo.dnom three.dnom four.dnom five.dnomsix.dnom seven.dnom eight.dnom nine.dnomparenleft.dnomparenright.dnom period.dnom comma.dnom zero.numrone.numrtwo.numr three.numr four.numr five.numrsix.numr seven.numr eight.numr nine.numrparenleft.numrparenright.numr period.numr comma.numr ordfeminine.aa.supsb.supsc.supsd.supse.supsf.supsg.supsh.supsi.supsj.supsk.supsl.supsm.supsn.supso.supsp.supsq.supsr.supss.supst.supsu.supsv.supsw.supsx.supsy.supsz.sups egrave.sups eacute.sups eogonek.sups uni0259.sups uni0266.supsuni02E0uni02E4a.supag.supai.supa colon.sups hyphen.sups endash.sups emdash.supsEurouni0192 colonmonetarylirauni20A6pesetauni20A9donguni20B1uni20B2uni20B4uni20B5uni20B9uni20BAuni20AEuni20B8uni20BDuni2215 slash.fraconethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215Auni2150 oneeighth threeeighths fiveeighths seveneighthsuni2151uni2152uni2189uni2219 equivalence revlogicalnot intersection orthogonaluni2032uni2033uni2035uni00B5 integraltp integralbtuni2206uni2126uni2200uni2203uni2237uni2105uni2113 estimateduni2190arrowupuni2192 arrowdownuni2196uni2197uni2198uni2199uni21D0uni21D1uni21D2uni21D3 arrowboth arrowupdn arrowupdnbseuni25CFuni25CBuni25A0uni25A1uni2752uni25C6triagupuni25B3uni25B6uni25B7triagdnuni25BDuni25C0uni25C1triagrttriaglf invcircleuni25C9uni2610uni2611uni2713 musicalnotemusicalnotedblheartclubdiamondspade smileface invsmilefaceuni2764uni2615u1F4A9u1F916u1F512femalemalesunhouseuni02B9uni02BBuni02BCuni02BEuni02BFuni02C1uni02D0uni02D1uni02DEuni02C8uni02C9uni02CAuni02CBuni02CCuni25CCuni0300 uni0300.capuni0340uni0301 uni0301.cap uni0301.guni0302 uni0302.capuni0303 uni0303.capuni0304 uni0304.capuni0305 uni0305.capuni0306 uni0306.c uni0306.cap uni0306.ccapuni0307 uni0307.capuni0308 uni0308.capuni0309 uni0309.capuni0310 uni0310.capuni030A uni030A.capuni030B uni030B.capuni030C uni030C.cap uni030C.auni030F uni030F.capuni0311 uni0311.capuni0312 uni0312.guni0313uni0343uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320uni0323uni0324uni0325uni0326 uni0326.auni0327 uni0327.capuni0328 uni0328.capuni0329uni032Auni032Cuni032Euni032Funi0330uni0331uni0334uni0339uni033Auni033Buni033Cuni033Duni0342 uni0342.capuni0345uni035Funi0361 uni03080301uni03080301.cap uni03080301.g uni03080300uni03080300.cap uni03080300.g uni03080303 uni03080304uni03080304.cap uni0308030Cuni0308030C.cap uni03020301uni03020301.cap uni03020300uni03020300.cap uni03020309uni03020309.cap uni03020303uni03020303.cap uni03060301uni03060301.cap uni03060300uni03060300.cap uni03060309uni03060309.cap uni03060303uni03060303.cap uni03020306uni03020306.cap uni03040301uni03040301.cap uni030C0307uni030C0307.cap uni03120301 uni03120300 uni03120303 uni03130301 uni03130300 uni03130303uni00A0uni2007 space.frac nbspace.fracuni2500uni2501uni2502uni2503uni2504uni2505uni2506uni2507uni2508uni2509uni250Auni250Buni250Cuni250Duni250Euni250Funi2510uni2511uni2512uni2513uni2514uni2515uni2516uni2517uni2518uni2519uni251Auni251Buni251Cuni251Duni251Euni251Funi2520uni2521uni2522uni2523uni2524uni2525uni2526uni2527uni2528uni2529uni252Auni252Buni252Cuni252Duni252Euni252Funi2530uni2531uni2532uni2533uni2534uni2535uni2536uni2537uni2538uni2539uni253Auni253Buni253Cuni253Duni253Euni253Funi2540uni2541uni2542uni2543uni2544uni2545uni2546uni2547uni2548uni2549uni254Auni254Buni254Cuni254Duni254Euni254Funi2550uni2551uni2552uni2553uni2554uni2555uni2556uni2557uni2558uni2559uni255Auni255Buni255Cuni255Duni255Euni255Funi2560uni2561uni2562uni2563uni2564uni2565uni2566uni2567uni2568uni2569uni256Auni256Buni256Cuni256Duni256Euni256Funi2570uni2571uni2572uni2573uni2574uni2575uni2576uni2577uni2578uni2579uni257Auni257Buni257Cuni257Duni257Euni257Funi2580uni2581uni2582uni2583uni2584uni2585uni2586uni2587uni2588uni2589uni258Auni258Buni258Cuni258Duni258Euni258Funi2590uni2591uni2592uni2593uni2594uni2595uni2596uni2597uni2598uni2599uni259Auni259Buni259Cuni259Duni259Euni259Funi202FuniFEFFu1F3B5u1F3B6f_if_luniE0A0uniE0A1uniE0A2uniE0B0uniE0B1uniE0B2uniE0B3ideoromnDFLTcyrlgreklatn V t  !!""#')13577::==@@MM[[^^eevv    $$**00??BBQQUU\\aassww    ##&&56;;?@HHLNQRYY\^bbddffllnnqquu  $%'-0146KLeeEHn#11BDHn (DFLTcyrl.grekXlatnl SRB  ! " #ATH &NSM 6SKS F $ %&'(ccmpccmpccmpccmp ccmpccmpccmp"ccmp*frac2frac8frac>fracDfracJfracPfracVfrac\markbmarkvmarkmarkmarkmarkmarkmarkmkmkmkmkmkmkmkmkmkmkmkmk mkmk&mkmk,size2size6size:size>sizeBsizeFsizeJsizeN                 d&.8BJT\dlt|vxzb| n   Z  P t     2    X X V v  ZSx~xxxxxxxxxr rr&x,2xxx8xx>Drr  DJPV\bhntzrrrrJrrrrD DxxxxxxJr"x(xx.(xx,x4:@FrrrrLrRrr,,ZKVJDF@.0<=@Z\>A0d/'B+B\D?%"T`n-6N#{&GFjJ%,22HHHNP(:]M<X Z `   , D L hh.djpv|^^^^^^,^Fz]?@Z'*bk:6N jZZZZZZZZZZZZZZZZZZZZZZZ} &,28>DJPV\bhntz8b&VhznDDV2Dhz "(.4:@FLRX^2Vdddddddjp,X&MJR]@9.<6T0#:\%O%%5| %P"2i%h3%&%F,a%%%e%W%%0%H%6%%`|%/NK%H  ,Q Q ", HHDJ>>>>PV>\bDDDh>nPPPtV>JJJJzz>,d6P2 ZShnhhnhhnhnhnhnhhnnhnhnhnhnhnhnhnhnhnhhhhhhhnhnhhnhhhnhnhnhnhnhnhnhnhnhnhnhnhnhhhhhh &&,28822>DJP,,,j,,L,>,,i,[,TGF,!#$%&'/(a #"%+,4 hjFGE JJJMMKinLR# 11(BD)Hn, !#$%&')*+,-./01345@M[e QUaw    56?@HLMNQRY\]^bdflnqu $%'()*+,-01456KLe&23. !#$')*-./035MU?@LRY\]$%(06< >AEE} !#$%&')*+,-./01345M[Ua    6?@LQRY\]^du= 'R'*45 $*047:=^ *Us #&?@     DFLTcyrlfgreklatnR! (08@HPX`hpx SRB T" !)19AIQYaiqy" "*2:BJRZbjrz" #+3;CKS[cks{ATH ^NSM SKS ! $,4<DLT\dlt| ! %-5=EMU]emu} "&.6>FNV^fnv~ "'/7?GOW_gow  casePcaseVcase\casebcasehcasencasetcasezccmpccmpccmpccmpccmpccmpccmpccmpcv01cv01cv01cv01cv01cv01cv01cv01cv02 cv02&cv02,cv022cv028cv02>cv02Dcv02Jcv04Pcv04Vcv04\cv04bcv04hcv04ncv04tcv04zcv06cv06cv06cv06cv06cv06cv06cv06cv07cv07cv07cv07cv07cv07cv07cv07cv08cv08cv08cv08cv08cv08cv08cv08 cv09cv09cv09cv09"cv09(cv09.cv094cv09:cv10@cv10Fcv10Lcv10Rcv10Xcv10^cv10dcv10jcv11pcv11vcv11|cv11cv11cv11cv11cv11cv12cv12cv12cv12cv12cv12cv12cv12cv14cv14cv14cv14cv14cv14cv14cv14cv15 cv15 cv15 cv15 cv15 cv15 cv15 $cv15 *cv16 0cv16 6cv16 ss06 Dss06 Jss07 Pss07 Vss07 \ss07 bss07 hss07 nss07 tss07 zsubs subs subs subs subs subs subs subs sups sups sups sups sups sups sups sups zerozerozero zerozerozerozero$zero*        @:4.(" ~xrltnhb\VPJRLF@:4.(0*$ ~ztnhb\                                  ~tj`VPJD>82,&$              $JRZbjr~&.6>FNV^fn,*0.,z 2<x Vh!#L  &,28>DJP  ** U!!":d $USYc W $][a_aC$*06<KMHJNOQNC &,jjiikkC &,mmllnnC,6@JT`jt~@4e4v4 44 4$04 B?2Q4'\w44;2*v"d" !$%"#    ###)*+,-./0123456789:;<=>?@ABCDEFGrMNOP N R9  35CILPRTVXZ\^`bdfP !"#$%&'(5)*+,-./01234ef'J: 6789:;<=>K6 ?RABCDEFGHIJK@STUVWXYZ[L\]NPhijL4444 8C<<< < @ M4N4*(UMOQNP  35CILPRTVXZ\^`bdf(q    r "   _b+.qtA_+q b.tA$4   CHKOQSUWY[]_ace?$%QHL !#  "$'*/06 6Y[[>]x?zz[|\^~!   24CHKOQSUWY[]_ace!  35CILPRTVXZ\^`bdfmv  !o hj% qr5)*00mv9mnopqrstuvxyz{|}~   24CHKOQSUWY[]_ace\\&&))"";B//  $'JKLMNOPQRSTU[\]^_`abMO@A[1myRnnz$?($%QHL   24CHKOQSUWY[]_ace%ooPK!TB3generator/template/darkfish/_sidebar_in_files.rhtmlnu[ PK!@@'generator/template/darkfish/index.rhtmlnu[
    <%- if @options.main_page and main_page = @files.find { |f| f.full_name == @options.main_page } then %> <%= main_page.description %> <%- else -%>

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

    PK!3^^)generator/template/darkfish/_footer.rhtmlnu[ PK!7'generator/template/darkfish/class.rhtmlnu[

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

    <%= klass.description %>
    <%- klass.each_section do |section, constants, attributes| -%>
    <%- if section.title then -%>

    <%= section.title %>

    ↑ top
    <%- end -%> <%- if section.comment then -%>
    <%= section.description %>
    <%- end -%> <%- unless constants.empty? then -%>

    Constants

    <%- constants.each do |const| -%>
    <%= const.name %> <%- if const.comment then -%>
    <%= const.description.strip %> <%- else -%>
    (Not documented) <%- end -%> <%- end -%>
    <%- end -%> <%- unless attributes.empty? then -%>

    Attributes

    <%- attributes.each do |attrib| -%>
    <%= h attrib.name %>[<%= attrib.rw %>]
    <%- if attrib.comment then -%> <%= attrib.description.strip %> <%- else -%>

    (Not documented) <%- end -%>

    <%- end -%>
    <%- end -%> <%- klass.methods_by_type(section).each do |type, visibilities| next if visibilities.empty? visibilities.each do |visibility, methods| next if methods.empty? %>

    <%= visibility.to_s.capitalize %> <%= type.capitalize %> Methods

    <%- methods.each do |method| -%>
    ">
    <%- if (call_seq = method.call_seq) then -%> <%- call_seq.strip.split("\n").each_with_index do |call_seq, i| -%>
    <%= h(call_seq.strip. gsub( /^\w+\./m, '')). gsub(/(.*)[-=]>/, '\1→') %> <%- if i == 0 and method.token_stream then -%> click to toggle source <%- end -%>
    <%- end -%> <%- else -%>
    <%= h method.name %><%= h method.param_seq %> <%- if method.token_stream then -%> click to toggle source <%- end -%>
    <%- end -%>
    <%- if method.comment then -%> <%= method.description.strip %> <%- else -%>

    (Not documented) <%- end -%> <%- if method.calls_super then -%>

    Calls superclass method <%= method.superclass_method ? method.formatter.link(method.superclass_method.full_name, method.superclass_method.full_name) : nil %>
    <%- end -%> <%- if method.token_stream then -%>
    <%= method.markup_code %>
    <%- end -%>
    <%- unless method.aliases.empty? then -%>
    Also aliased as: <%= method.aliases.map do |aka| if aka.parent then # HACK lib/rexml/encodings %{#{h aka.name}} else h aka.name end end.join ", " %>
    <%- end -%> <%- if method.is_alias_for then -%> <%- end -%>
    <%- end -%>
    <%- end end %>
    <%- end -%>
    PK! O2]]4generator/template/darkfish/_sidebar_installed.rhtmlnu[ PK! NNN3generator/template/darkfish/servlet_not_found.rhtmlnu[

    Not Found

    <%= message %>

    PK!QCC3generator/template/darkfish/_sidebar_sections.rhtmlnu[<%- unless klass.sections.length == 1 then %> <%- end -%> PK!  3generator/template/darkfish/table_of_contents.rhtmlnu[

    <%= h @title %>

    <%- simple_files = @files.select { |f| f.text? } -%> <%- unless simple_files.empty? then -%>

    Pages

      <%- simple_files.sort.each do |file| -%>
    • <%= h file.page_name %> <% # HACK table_of_contents should not exist on Document table = file.parse(file.comment).table_of_contents unless table.empty? then %> <%- end -%>
    • <%- end -%>
    <%- end -%>

    Classes and Modules

      <%- @modsort.each do |klass| -%>
    • <%= klass.full_name %> <%- table = [] table.concat klass.parse(klass.comment_location).table_of_contents table.concat klass.section_contents unless table.empty? then %> <%- end -%>
    • <%- end -%>

    Methods

      <%- @store.all_classes_and_modules.map do |mod| mod.method_list end.flatten.sort.each do |method| %>
    • <%= h method.pretty_name %><%= method.parent.full_name %> <%- end -%>
    PK!Љ5cc2generator/template/darkfish/_sidebar_classes.rhtmlnu[ PK!E`2generator/template/darkfish/_sidebar_methods.rhtmlnu[<%- unless klass.method_list.empty? then %> <%- end -%> PK!53generator/template/darkfish/_sidebar_includes.rhtmlnu[<%- unless klass.includes.empty? then %> <%- end -%> PK!΍  (generator/template/darkfish/js/search.jsnu[Search = function(data, input, result) { this.data = data; this.input = input; this.result = result; this.current = null; this.view = this.result.parentNode; this.searcher = new Searcher(data.index); this.init(); } Search.prototype = Object.assign({}, Navigation, new function() { var suid = 1; this.init = function() { var _this = this; var observer = function(e) { switch(e.keyCode) { case 38: // Event.KEY_UP case 40: // Event.KEY_DOWN return; } _this.search(_this.input.value); }; this.input.addEventListener('keyup', observer); this.input.addEventListener('click', observer); // mac's clear field this.searcher.ready(function(results, isLast) { _this.addResults(results, isLast); }) this.initNavigation(); this.setNavigationActive(false); } this.search = function(value, selectFirstMatch) { value = value.trim().toLowerCase(); if (value) { this.setNavigationActive(true); } else { this.setNavigationActive(false); } if (value == '') { this.lastQuery = value; this.result.innerHTML = ''; this.result.setAttribute('aria-expanded', 'false'); this.setNavigationActive(false); } else if (value != this.lastQuery) { this.lastQuery = value; this.result.setAttribute('aria-busy', 'true'); this.result.setAttribute('aria-expanded', 'true'); this.firstRun = true; this.searcher.find(value); } } this.addResults = function(results, isLast) { var target = this.result; if (this.firstRun && (results.length > 0 || isLast)) { this.current = null; this.result.innerHTML = ''; } for (var i=0, l = results.length; i < l; i++) { var item = this.renderItem.call(this, results[i]); item.setAttribute('id', 'search-result-' + target.childElementCount); target.appendChild(item); }; if (this.firstRun && results.length > 0) { this.firstRun = false; this.current = target.firstChild; this.current.classList.add('search-selected'); } //TODO: ECMAScript //if (jQuery.browser.msie) this.$element[0].className += ''; if (isLast) this.result.setAttribute('aria-busy', 'false'); } this.move = function(isDown) { if (!this.current) return; var next = isDown ? this.current.nextElementSibling : this.current.previousElementSibling; if (next) { this.current.classList.remove('search-selected'); next.classList.add('search-selected'); this.input.setAttribute('aria-activedescendant', next.getAttribute('id')); this.scrollIntoView(next, this.view); this.current = next; this.input.value = next.firstChild.firstChild.text; this.input.select(); } return true; } this.hlt = function(html) { return this.escapeHTML(html). replace(/\u0001/g, ''). replace(/\u0002/g, ''); } this.escapeHTML = function(html) { return html.replace(/[&<>"`']/g, function(c) { return '&#' + c.charCodeAt(0) + ';'; }); } }); PK!ll]D D *generator/template/darkfish/js/darkfish.jsnu[/** * * 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-heading').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 <%- @options.template_stylesheets.each do |stylesheet| -%> <%- end -%> PK!*f1generator/template/darkfish/_sidebar_search.rhtmlnu[ PK! generator/markup.rbnu[# 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.rdoc.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 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.rdoc.options.webcvs if /%s/ =~ url then url % @relative_name else url + @relative_name end end end PK!qgenerator/json_index.rbnu[# 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. +parent_generator+ is used to determine the # class_dir and file_dir of links in the output index. # # +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.map do |klass| klass.method_list end.flatten.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 ## # The directory classes are written to def class_dir @parent_generator.class_dir end ## # The directory files are written to def file_dir @parent_generator.file_dir 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 PK!P Q Qgenerator/darkfish.rbnu[# 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 ] ## # Path to this file's parent directory. Used to find templates and other # resources. GENERATOR_DIR = File.join 'rdoc', 'generator' ## # 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 ## # Directory where generated class HTML files live relative to the output # dir. def class_dir nil end ## # Directory where generated class HTML files live relative to the output # dir. def file_dir nil 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 setup 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 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 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 setup 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 svninfo = get_svninfo(current) @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.local_variable_set(:svninfo, svninfo) here end end ## # Generate a documentation file for each class and module def generate_class_files setup 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 setup 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 setup 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 setup 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 setup 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 setup 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.map { |m| m.method_list }.flatten.sort @modsort = get_sorted_module_list @classes end ## # Return a string describing the amount of time in the given number of # seconds in terms a human can understand easily. def time_delta_string seconds return 'less than a minute' if seconds < 60 return "#{seconds / 60} minute#{seconds / 60 == 1 ? '' : 's'}" if seconds < 3000 # 50 minutes return 'about one hour' if seconds < 5400 # 90 minutes return "#{seconds / 3600} hours" if seconds < 64800 # 18 hours return 'one day' if seconds < 86400 # 1 day return 'about one day' if seconds < 172800 # 2 days return "#{seconds / 86400} days" if seconds < 604800 # 1 week return 'about one week' if seconds < 1209600 # 2 week return "#{seconds / 604800} weeks" if seconds < 7257600 # 3 months return "#{seconds / 2419200} months" if seconds < 31536000 # 1 year return "#{seconds / 31536000} years" end # %q$Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $" SVNID_PATTERN = / \$Id:\s (\S+)\s # filename (\d+)\s # rev (\d{4}-\d{2}-\d{2})\s # Date (YYYY-MM-DD) (\d{2}:\d{2}:\d{2}Z)\s # Time (HH:MM:SSZ) (\w+)\s # committer \$$ /x ## # Try to extract Subversion information out of the first constant whose # value looks like a subversion Id tag. If no matching constant is found, # and empty hash is returned. def get_svninfo klass constants = klass.constants or return {} constants.find { |c| c.value =~ SVNID_PATTERN } or return {} filename, rev, date, time, committer = $~.captures commitdate = Time.parse "#{date} #{time}" return { :filename => filename, :rev => Integer(rev), :commitdate => commitdate, :commitdelta => time_delta_string(Time.now - commitdate), :committer => committer, } end ## # Creates a template from its components and the +body_file+. # # For backwards compatibility, if +body_file+ contains " #{head_file.read} #{body} #{footer_file.read} 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 if RUBY_VERSION >= '2.6' template = klass.new template, trim_mode: '-', eoutvar: erbout else template = klass.new template, nil, '-', erbout end @template_cache[file] = template template end end PK!f=wgenerator/ri.rbnu[# 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 PK!v($($method_attr.rbnu[# 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 ## # Pretty parameter list for this method attr_reader :param_seq ## # 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 super() @text = text @name = name @aliases = [] @is_alias_for = nil @parent_name = nil @singleton = nil @visibility = :public @see = false @arglists = nil @block_params = nil @call_seq = nil @param_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] <=> [other.singleton ? 0 : 1, 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/util' 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 ## # Name for output to HTML. For class methods the full name with a "." is # used like +SomeClass.method_name+. For instance methods the class name is # used if +context+ does not match the parent. # # This is to help prevent people from using :: to call class methods. def output_name context return "#{name_prefix}#{@name}" if context == parent "#{parent_name}#{@singleton ? '.' : '#'}#{@name}" 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 end PK!ʥ9e tom_doc.rbnu[# frozen_string_literal: true # :markup: tomdoc # A parser for TomDoc based on TomDoc 1.0.0-rc1 (02adef9b5a) # # The TomDoc specification can be found at: # # http://tomdoc.org # # The latest version of the TomDoc specification can be found at: # # https://github.com/mojombo/tomdoc/blob/master/tomdoc.md # # To choose TomDoc as your only default format see RDoc::Options@Saved+Options # for instructions on setting up a .rdoc_options file to store # your project default. # # There are a few differences between this parser and the specification. A # best-effort was made to follow the specification as closely as possible but # some choices to deviate were made. # # A future version of RDoc will warn when a MUST or MUST NOT is violated and # may warn when a SHOULD or SHOULD NOT is violated. RDoc will always try # to emit documentation even if given invalid TomDoc. # # Here are some implementation choices this parser currently makes: # # This parser allows rdoc-style inline markup but you should not depended on # it. # # This parser allows a space between the comment and the method body. # # This parser does not require the default value to be described for an # optional argument. # # This parser does not examine the order of sections. An Examples section may # precede the Arguments section. # # This class is documented in TomDoc format. Since this is a subclass of the # RDoc markup parser there isn't much to see here, unfortunately. class RDoc::TomDoc < RDoc::Markup::Parser # Internal: Token accessor attr_reader :tokens # Internal: Adds a post-processor which sets the RDoc section based on the # comment's status. # # Returns nothing. def self.add_post_processor # :nodoc: RDoc::Markup::PreProcess.post_process do |comment, code_object| next unless code_object and RDoc::Comment === comment and comment.format == 'tomdoc' comment.text.gsub!(/(\A\s*# )(Public|Internal|Deprecated):\s+/) do section = code_object.add_section $2 code_object.temporary_section = section $1 end end end add_post_processor # Public: Parses TomDoc from text # # text - A String containing TomDoc-format text. # # Examples # # RDoc::TomDoc.parse <<-TOMDOC # This method does some things # # Returns nothing. # TOMDOC # # => # # # Returns an RDoc::Markup::Document representing the TomDoc format. def self.parse text parser = new parser.tokenize text doc = RDoc::Markup::Document.new parser.parse doc doc end # Internal: Extracts the Signature section's method signature # # comment - An RDoc::Comment that will be parsed and have the signature # extracted # # Returns a String containing the signature and nil if not def self.signature comment return unless comment.tomdoc? document = comment.parse signature = nil found_heading = false found_signature = false document.parts.delete_if do |part| next false if found_signature found_heading ||= RDoc::Markup::Heading === part && part.text == 'Signature' next false unless found_heading next true if RDoc::Markup::BlankLine === part if RDoc::Markup::Verbatim === part then signature = part found_signature = true end end signature and signature.text end # Public: Creates a new TomDoc parser. See also RDoc::Markup::parse def initialize super @section = nil @seen_returns = false end # Internal: Builds a heading from the token stream # # level - The level of heading to create # # Returns an RDoc::Markup::Heading def build_heading level heading = super @section = heading.text heading end # Internal: Builds a verbatim from the token stream. A verbatim in the # Examples section will be marked as in Ruby format. # # margin - The indentation from the margin for lines that belong to this # verbatim section. # # Returns an RDoc::Markup::Verbatim def build_verbatim margin verbatim = super verbatim.format = :ruby if @section == 'Examples' verbatim end # Internal: Builds a paragraph from the token stream # # margin - Unused # # Returns an RDoc::Markup::Paragraph. def build_paragraph margin p :paragraph_start => margin if @debug paragraph = RDoc::Markup::Paragraph.new until @tokens.empty? do type, data, = get case type when :TEXT then @section = 'Returns' if data =~ /\A(Returns|Raises)/ paragraph << data when :NEWLINE then if :TEXT == peek_token[0] then # Lines beginning with 'Raises' in the Returns section should not be # treated as multiline text if 'Returns' == @section and peek_token[1].start_with?('Raises') then break else paragraph << ' ' end else break end else unget break end end p :paragraph_end => margin if @debug paragraph end ## # Detects a section change to "Returns" and adds a heading def parse_text parent, indent # :nodoc: paragraph = build_paragraph indent if false == @seen_returns and 'Returns' == @section then @seen_returns = true parent << RDoc::Markup::Heading.new(3, 'Returns') parent << RDoc::Markup::BlankLine.new end parent << paragraph end # Internal: Turns text into an Array of tokens # # text - A String containing TomDoc-format text. # # Returns self. def tokenize text text = text.sub(/\A(Public|Internal|Deprecated):\s+/, '') setup_scanner text until @s.eos? do pos = @s.pos # leading spaces will be reflected by the column of the next token # the only thing we loose are trailing spaces at the end of the file next if @s.scan(/ +/) @tokens << case when @s.scan(/\r?\n/) then token = [:NEWLINE, @s.matched, *pos] @s.newline! token when @s.scan(/(Examples|Signature)$/) then @tokens << [:HEADER, 3, *pos] [:TEXT, @s[1], *pos] when @s.scan(/([:\w][\w\[\]]*)[ ]+- /) then [:NOTE, @s[1], *pos] else @s.scan(/.*/) [:TEXT, @s.matched.sub(/\r$/, ''), *pos] end end self end end PK!Detask.rbnu[# frozen_string_literal: true #-- # Copyright (c) 2003, 2004 Jim Weirich, 2009 Eric Hodel # # 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. #++ begin gem 'rdoc' rescue Gem::LoadError end unless defined?(RDoc) begin gem 'rake' rescue Gem::LoadError end unless defined?(Rake) require_relative '../rdoc' require 'rake' require 'rake/tasklib' ## # RDoc::Task creates the following rake tasks to generate and clean up RDoc # output: # # [rdoc] # Main task for this RDoc task. # # [clobber_rdoc] # Delete all the rdoc files. This target is automatically added to the main # clobber target. # # [rerdoc] # Rebuild the rdoc files from scratch, even if they are not out of date. # # Simple Example: # # require 'rdoc/task' # # RDoc::Task.new do |rdoc| # rdoc.main = "README.rdoc" # rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb") # end # # The +rdoc+ object passed to the block is an RDoc::Task object. See the # attributes list for the RDoc::Task class for available customization options. # # == Specifying different task names # # You may wish to give the task a different name, such as if you are # generating two sets of documentation. For instance, if you want to have a # development set of documentation including private methods: # # require 'rdoc/task' # # RDoc::Task.new :rdoc_dev do |rdoc| # rdoc.main = "README.rdoc" # rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb") # rdoc.options << "--all" # end # # The tasks would then be named :rdoc_dev, # :clobber_rdoc_dev, and :rerdoc_dev. # # If you wish to have completely different task names, then pass a Hash as # first argument. With the :rdoc, :clobber_rdoc and # :rerdoc options, you can customize the task names to your liking. # # For example: # # require 'rdoc/task' # # RDoc::Task.new(:rdoc => "rdoc", :clobber_rdoc => "rdoc:clean", # :rerdoc => "rdoc:force") # # This will create the tasks :rdoc, :rdoc:clean and # :rdoc:force. class RDoc::Task < Rake::TaskLib ## # Name of the main, top level task. (default is :rdoc) attr_accessor :name ## # Comment markup format. rdoc, rd and tomdoc are supported. (default is # 'rdoc') attr_accessor :markup ## # Name of directory to receive the html output files. (default is "html") attr_accessor :rdoc_dir ## # Title of RDoc documentation. (defaults to rdoc's default) attr_accessor :title ## # Name of file to be used as the main, top level file of the RDoc. (default # is none) attr_accessor :main ## # Name of template to be used by rdoc. (defaults to rdoc's default) attr_accessor :template ## # Name of format generator (--format) used by rdoc. (defaults to # rdoc's default) attr_accessor :generator ## # List of files to be included in the rdoc generation. (default is []) attr_accessor :rdoc_files ## # Additional list of options to be passed rdoc. (default is []) attr_accessor :options ## # Whether to run the rdoc process as an external shell (default is false) attr_accessor :external ## # Create an RDoc task with the given name. See the RDoc::Task class overview # for documentation. def initialize name = :rdoc # :yield: self defaults check_names name @name = name yield self if block_given? define end ## # Ensures that +names+ only includes names for the :rdoc, :clobber_rdoc and # :rerdoc. If other names are given an ArgumentError is raised. def check_names names return unless Hash === names invalid_options = names.keys.map { |k| k.to_sym } - [:rdoc, :clobber_rdoc, :rerdoc] unless invalid_options.empty? then raise ArgumentError, "invalid options: #{invalid_options.join ', '}" end end ## # Task description for the clobber rdoc task or its renamed equivalent def clobber_task_description "Remove RDoc HTML files" end ## # Sets default task values def defaults @name = :rdoc @rdoc_files = Rake::FileList.new @rdoc_dir = 'html' @main = nil @title = nil @template = nil @generator = nil @options = [] end ## # All source is inline now. This method is deprecated def inline_source # :nodoc: warn "RDoc::Task#inline_source is deprecated" true end ## # All source is inline now. This method is deprecated def inline_source=(value) # :nodoc: warn "RDoc::Task#inline_source is deprecated" end ## # Create the tasks defined by this task lib. def define desc rdoc_task_description task rdoc_task_name desc rerdoc_task_description task rerdoc_task_name => [clobber_task_name, rdoc_task_name] desc clobber_task_description task clobber_task_name do rm_r @rdoc_dir rescue nil end task :clobber => [clobber_task_name] directory @rdoc_dir rdoc_target_deps = [ @rdoc_files, Rake.application.rakefile ].flatten.compact task rdoc_task_name => [rdoc_target] file rdoc_target => rdoc_target_deps do @before_running_rdoc.call if @before_running_rdoc args = option_list + @rdoc_files $stderr.puts "rdoc #{args.join ' '}" if Rake.application.options.trace RDoc::RDoc.new.document args end self end ## # List of options that will be supplied to RDoc def option_list result = @options.dup result << "-o" << @rdoc_dir result << "--main" << main if main result << "--markup" << markup if markup result << "--title" << title if title result << "-T" << template if template result << '-f' << generator if generator result end ## # The block passed to this method will be called just before running the # RDoc generator. It is allowed to modify RDoc::Task attributes inside the # block. def before_running_rdoc(&block) @before_running_rdoc = block end ## # Task description for the rdoc task or its renamed equivalent def rdoc_task_description 'Build RDoc HTML files' end ## # Task description for the rerdoc task or its renamed description def rerdoc_task_description "Rebuild RDoc HTML files" end private def rdoc_target "#{rdoc_dir}/created.rid" end def rdoc_task_name case name when Hash then (name[:rdoc] || "rdoc").to_s else name.to_s end end def clobber_task_name case name when Hash then (name[:clobber_rdoc] || "clobber_rdoc").to_s else "clobber_#{name}" end end def rerdoc_task_name case name when Hash then (name[:rerdoc] || "rerdoc").to_s else "re#{name}" end end end # :stopdoc: module Rake ## # For backwards compatibility RDocTask = RDoc::Task # :nodoc: end # :startdoc: PK!- % %code_object.rbnu[# 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::Mixin # * RDoc::Require # * RDoc::Include 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 ## # We are the model of the code, but we know that at some point we will be # worked on by viewers. By implementing the Viewable protocol, viewers can # associated themselves with these objects. attr_accessor :viewer ## # 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 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::Markup::Document then comment 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 ## # Yields each parent of this CodeObject. See also # RDoc::ClassModule#each_ancestor def each_parent code_object = self while code_object = code_object.parent do yield code_object end 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 if @store and @store.rdoc then @store.rdoc.options else RDoc::Options.new end 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 ## # File name of our parent def parent_file_name @parent ? @parent.base_name : '(unknown)' 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 PK!S2 i18n/text.rbnu[# frozen_string_literal: true ## # An i18n supported text. # # This object provides the following two features: # # * Extracts translation messages from wrapped raw text. # * Translates wrapped raw text in specified locale. # # Wrapped raw text is one of String, RDoc::Comment or Array of them. class RDoc::I18n::Text ## # Creates a new i18n supported text for +raw+ text. def initialize(raw) @raw = raw end ## # Extracts translation target messages and yields each message. # # Each yielded message is a Hash. It consists of the followings: # # :type :: :paragraph # :paragraph :: String (The translation target message itself.) # :line_no :: Integer (The line number of the :paragraph is started.) # # The above content may be added in the future. def extract_messages parse do |part| case part[:type] when :empty_line # ignore when :paragraph yield(part) end end end # Translates raw text into +locale+. def translate(locale) translated_text = '' parse do |part| case part[:type] when :paragraph translated_text += locale.translate(part[:paragraph]) when :empty_line translated_text += part[:line] else raise "should not reach here: unexpected type: #{type}" end end translated_text end private def parse(&block) paragraph = '' paragraph_start_line = 0 line_no = 0 each_line(@raw) do |line| line_no += 1 case line when /\A\s*\z/ if paragraph.empty? emit_empty_line_event(line, line_no, &block) else paragraph += line emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block) paragraph = '' end else paragraph_start_line = line_no if paragraph.empty? paragraph += line end end unless paragraph.empty? emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block) end end def each_line(raw, &block) case raw when RDoc::Comment raw.text.each_line(&block) when Array raw.each do |comment, location| each_line(comment, &block) end else raw.each_line(&block) end end def emit_empty_line_event(line, line_no) part = { :type => :empty_line, :line => line, :line_no => line_no, } yield(part) end def emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block) paragraph_part = { :type => :paragraph, :line_no => paragraph_start_line, } match_data = /(\s*)\z/.match(paragraph) if match_data paragraph_part[:paragraph] = match_data.pre_match yield(paragraph_part) emit_empty_line_event(match_data[1], line_no, &block) else paragraph_part[:paragraph] = paragraph yield(paragraph_part) end end end PK!KzVf f i18n/locale.rbnu[# frozen_string_literal: true ## # A message container for a locale. # # This object provides the following two features: # # * Loads translated messages from .po file. # * Translates a message into the locale. class RDoc::I18n::Locale @@locales = {} # :nodoc: class << self ## # Returns the locale object for +locale_name+. def [](locale_name) @@locales[locale_name] ||= new(locale_name) end ## # Sets the locale object for +locale_name+. # # Normally, this method is not used. This method is useful for # testing. def []=(locale_name, locale) @@locales[locale_name] = locale end end ## # The name of the locale. It uses IETF language tag format # +[language[_territory][.codeset][@modifier]]+. # # See also {BCP 47 - Tags for Identifying # Languages}[http://tools.ietf.org/rfc/bcp/bcp47.txt]. attr_reader :name ## # Creates a new locale object for +name+ locale. +name+ must # follow IETF language tag format. def initialize(name) @name = name @messages = {} end ## # Loads translation messages from +locale_directory+/+@name+/rdoc.po # or +locale_directory+/+@name+.po. The former has high priority. # # This method requires gettext gem for parsing .po file. If you # don't have gettext gem, this method doesn't load .po file. This # method warns and returns +false+. # # Returns +true+ if succeeded, +false+ otherwise. def load(locale_directory) return false if @name.nil? po_file_candidates = [ File.join(locale_directory, @name, 'rdoc.po'), File.join(locale_directory, "#{@name}.po"), ] po_file = po_file_candidates.find do |po_file_candidate| File.exist?(po_file_candidate) end return false unless po_file begin require 'gettext/po_parser' require 'gettext/mo' rescue LoadError warn('Need gettext gem for i18n feature:') warn(' gem install gettext') return false end po_parser = GetText::POParser.new messages = GetText::MO.new po_parser.report_warning = false po_parser.parse_file(po_file, messages) @messages.merge!(messages) true end ## # Translates the +message+ into locale. If there is no translation # messages for +message+ in locale, +message+ itself is returned. def translate(message) @messages[message] || message end end PK!(.ZZstore.rbnu[# frozen_string_literal: true require 'fileutils' ## # A set of rdoc data for a single project (gem, path, etc.). # # The store manages reading and writing ri data for a project and maintains a # cache of methods, classes and ancestors in the store. # # The store maintains a #cache of its contents for faster lookup. After # adding items to the store it must be flushed using #save_cache. The cache # contains the following structures: # # @cache = { # :ancestors => {}, # class name => ancestor names # :attributes => {}, # class name => attributes # :class_methods => {}, # class name => class methods # :instance_methods => {}, # class name => instance methods # :modules => [], # classes and modules in this store # :pages => [], # page names # } #-- # TODO need to prune classes class RDoc::Store ## # Errors raised from loading or saving the store class Error < RDoc::Error end ## # Raised when a stored file for a class, module, page or method is missing. class MissingFileError < Error ## # The store the file should exist in attr_reader :store ## # The file the #name should be saved as attr_reader :file ## # The name of the object the #file would be loaded from attr_reader :name ## # Creates a new MissingFileError for the missing +file+ for the given # +name+ that should have been in the +store+. def initialize store, file, name @store = store @file = file @name = name end def message # :nodoc: "store at #{@store.path} missing file #{@file} for #{@name}" end end ## # Stores the name of the C variable a class belongs to. This helps wire up # classes defined from C across files. attr_reader :c_enclosure_classes # :nodoc: attr_reader :c_enclosure_names # :nodoc: ## # Maps C variables to class or module names for each parsed C file. attr_reader :c_class_variables ## # Maps C variables to singleton class names for each parsed C file. attr_reader :c_singleton_class_variables ## # If true this Store will not write any files attr_accessor :dry_run ## # Path this store reads or writes attr_accessor :path ## # The RDoc::RDoc driver for this parse tree. This allows classes consulting # the documentation tree to access user-set options, for example. attr_accessor :rdoc ## # Type of ri datastore this was loaded from. See RDoc::RI::Driver, # RDoc::RI::Paths. attr_accessor :type ## # The contents of the Store attr_reader :cache ## # The encoding of the contents in the Store attr_accessor :encoding ## # The lazy constants alias will be discovered in passing attr_reader :unmatched_constant_alias ## # Creates a new Store of +type+ that will load or save to +path+ def initialize path = nil, type = nil @dry_run = false @encoding = nil @path = path @rdoc = nil @type = type @cache = { :ancestors => {}, :attributes => {}, :class_methods => {}, :c_class_variables => {}, :c_singleton_class_variables => {}, :encoding => @encoding, :instance_methods => {}, :main => nil, :modules => [], :pages => [], :title => nil, } @classes_hash = {} @modules_hash = {} @files_hash = {} @text_files_hash = {} @c_enclosure_classes = {} @c_enclosure_names = {} @c_class_variables = {} @c_singleton_class_variables = {} @unique_classes = nil @unique_modules = nil @unmatched_constant_alias = {} end ## # Adds +module+ as an enclosure (namespace) for the given +variable+ for C # files. def add_c_enclosure variable, namespace @c_enclosure_classes[variable] = namespace end ## # Adds C variables from an RDoc::Parser::C def add_c_variables c_parser filename = c_parser.top_level.relative_name @c_class_variables[filename] = make_variable_map c_parser.classes @c_singleton_class_variables[filename] = c_parser.singleton_classes end ## # Adds the file with +name+ as an RDoc::TopLevel to the store. Returns the # created RDoc::TopLevel. def add_file absolute_name, relative_name: absolute_name, parser: nil unless top_level = @files_hash[relative_name] then top_level = RDoc::TopLevel.new absolute_name, relative_name top_level.parser = parser if parser top_level.store = self @files_hash[relative_name] = top_level @text_files_hash[relative_name] = top_level if top_level.text? end top_level end def update_parser_of_file(absolute_name, parser) if top_level = @files_hash[absolute_name] then @text_files_hash[absolute_name] = top_level if top_level.text? end end ## # Returns all classes discovered by RDoc def all_classes @classes_hash.values end ## # Returns all classes and modules discovered by RDoc def all_classes_and_modules @classes_hash.values + @modules_hash.values end ## # All TopLevels known to RDoc def all_files @files_hash.values end ## # Returns all modules discovered by RDoc def all_modules modules_hash.values end ## # Ancestors cache accessor. Maps a klass name to an Array of its ancestors # in this store. If Foo in this store inherits from Object, Kernel won't be # listed (it will be included from ruby's ri store). def ancestors @cache[:ancestors] end ## # Attributes cache accessor. Maps a class to an Array of its attributes. def attributes @cache[:attributes] end ## # Path to the cache file def cache_path File.join @path, 'cache.ri' end ## # Path to the ri data for +klass_name+ def class_file klass_name name = klass_name.split('::').last File.join class_path(klass_name), "cdesc-#{name}.ri" end ## # Class methods cache accessor. Maps a class to an Array of its class # methods (not full name). def class_methods @cache[:class_methods] end ## # Path where data for +klass_name+ will be stored (methods or class data) def class_path klass_name File.join @path, *klass_name.split('::') end ## # Hash of all classes known to RDoc def classes_hash @classes_hash end ## # Removes empty items and ensures item in each collection are unique and # sorted def clean_cache_collection collection # :nodoc: collection.each do |name, item| if item.empty? then collection.delete name else # HACK mongrel-1.1.5 documents its files twice item.uniq! item.sort! end end end ## # Prepares the RDoc code object tree for use by a generator. # # It finds unique classes/modules defined, and replaces classes/modules that # are aliases for another one by a copy with RDoc::ClassModule#is_alias_for # set. # # It updates the RDoc::ClassModule#constant_aliases attribute of "real" # classes or modules. # # It also completely removes the classes and modules that should be removed # from the documentation and the methods that have a visibility below # +min_visibility+, which is the --visibility option. # # See also RDoc::Context#remove_from_documentation? def complete min_visibility fix_basic_object_inheritance # cache included modules before they are removed from the documentation all_classes_and_modules.each { |cm| cm.ancestors } unless min_visibility == :nodoc then remove_nodoc @classes_hash remove_nodoc @modules_hash end @unique_classes = find_unique @classes_hash @unique_modules = find_unique @modules_hash unique_classes_and_modules.each do |cm| cm.complete min_visibility end @files_hash.each_key do |file_name| tl = @files_hash[file_name] unless tl.text? then tl.modules_hash.clear tl.classes_hash.clear tl.classes_or_modules.each do |cm| name = cm.full_name if cm.type == 'class' then tl.classes_hash[name] = cm if @classes_hash[name] else tl.modules_hash[name] = cm if @modules_hash[name] end end end end end ## # Hash of all files known to RDoc def files_hash @files_hash end ## # Finds the enclosure (namespace) for the given C +variable+. def find_c_enclosure variable @c_enclosure_classes.fetch variable do break unless name = @c_enclosure_names[variable] mod = find_class_or_module name unless mod then loaded_mod = load_class_data name file = loaded_mod.in_files.first return unless file # legacy data source file.store = self mod = file.add_module RDoc::NormalModule, name end @c_enclosure_classes[variable] = mod end end ## # Finds the class with +name+ in all discovered classes def find_class_named name @classes_hash[name] end ## # Finds the class with +name+ starting in namespace +from+ def find_class_named_from name, from from = find_class_named from unless RDoc::Context === from until RDoc::TopLevel === from do return nil unless from klass = from.find_class_named name return klass if klass from = from.parent end find_class_named name end ## # Finds the class or module with +name+ def find_class_or_module name name = $' if name =~ /^::/ @classes_hash[name] || @modules_hash[name] end ## # Finds the file with +name+ in all discovered files def find_file_named name @files_hash[name] end ## # Finds the module with +name+ in all discovered modules def find_module_named name @modules_hash[name] end ## # Returns the RDoc::TopLevel that is a text file and has the given # +file_name+ def find_text_page file_name @text_files_hash.each_value.find do |file| file.full_name == file_name end end ## # Finds unique classes/modules defined in +all_hash+, # and returns them as an array. Performs the alias # updates in +all_hash+: see ::complete. #-- # TODO aliases should be registered by Context#add_module_alias def find_unique all_hash unique = [] all_hash.each_pair do |full_name, cm| unique << cm if full_name == cm.full_name end unique end ## # Fixes the erroneous BasicObject < Object in 1.9. # # Because we assumed all classes without a stated superclass # inherit from Object, we have the above wrong inheritance. # # We fix BasicObject right away if we are running in a Ruby # version >= 1.9. def fix_basic_object_inheritance basic = classes_hash['BasicObject'] return unless basic basic.superclass = nil end ## # Friendly rendition of #path def friendly_path case type when :gem then parent = File.expand_path '..', @path "gem #{File.basename parent}" when :home then RDoc.home when :site then 'ruby site' when :system then 'ruby core' else @path end end def inspect # :nodoc: "#<%s:0x%x %s %p>" % [self.class, object_id, @path, module_names.sort] end ## # Instance methods cache accessor. Maps a class to an Array of its # instance methods (not full name). def instance_methods @cache[:instance_methods] end ## # Loads all items from this store into memory. This recreates a # documentation tree for use by a generator def load_all load_cache module_names.each do |module_name| mod = find_class_or_module(module_name) || load_class(module_name) # load method documentation since the loaded class/module does not have # it loaded_methods = mod.method_list.map do |method| load_method module_name, method.full_name end mod.method_list.replace loaded_methods loaded_attributes = mod.attributes.map do |attribute| load_method module_name, attribute.full_name end mod.attributes.replace loaded_attributes end all_classes_and_modules.each do |mod| descendent_re = /^#{mod.full_name}::[^:]+$/ module_names.each do |name| next unless name =~ descendent_re descendent = find_class_or_module name case descendent when RDoc::NormalClass then mod.classes_hash[name] = descendent when RDoc::NormalModule then mod.modules_hash[name] = descendent end end end @cache[:pages].each do |page_name| page = load_page page_name @files_hash[page_name] = page @text_files_hash[page_name] = page if page.text? end end ## # Loads cache file for this store def load_cache #orig_enc = @encoding @cache = marshal_load(cache_path) load_enc = @cache[:encoding] # TODO this feature will be time-consuming to add: # a) Encodings may be incompatible but transcodeable # b) Need to warn in the appropriate spots, wherever they may be # c) Need to handle cross-cache differences in encodings # d) Need to warn when generating into a cache with different encodings # #if orig_enc and load_enc != orig_enc then # warn "Cached encoding #{load_enc} is incompatible with #{orig_enc}\n" \ # "from #{path}/cache.ri" unless # Encoding.compatible? orig_enc, load_enc #end @encoding = load_enc unless @encoding @cache[:pages] ||= [] @cache[:main] ||= nil @cache[:c_class_variables] ||= {} @cache[:c_singleton_class_variables] ||= {} @cache[:c_class_variables].each do |_, map| map.each do |variable, name| @c_enclosure_names[variable] = name end end @cache rescue Errno::ENOENT end ## # Loads ri data for +klass_name+ and hooks it up to this store. def load_class klass_name obj = load_class_data klass_name obj.store = self case obj when RDoc::NormalClass then @classes_hash[klass_name] = obj when RDoc::SingleClass then @classes_hash[klass_name] = obj when RDoc::NormalModule then @modules_hash[klass_name] = obj end end ## # Loads ri data for +klass_name+ def load_class_data klass_name file = class_file klass_name marshal_load(file) rescue Errno::ENOENT => e error = MissingFileError.new(self, file, klass_name) error.set_backtrace e.backtrace raise error end ## # Loads ri data for +method_name+ in +klass_name+ def load_method klass_name, method_name file = method_file klass_name, method_name obj = marshal_load(file) obj.store = self obj.parent ||= find_class_or_module(klass_name) || load_class(klass_name) obj rescue Errno::ENOENT => e error = MissingFileError.new(self, file, klass_name + method_name) error.set_backtrace e.backtrace raise error end ## # Loads ri data for +page_name+ def load_page page_name file = page_file page_name obj = marshal_load(file) obj.store = self obj rescue Errno::ENOENT => e error = MissingFileError.new(self, file, page_name) error.set_backtrace e.backtrace raise error end ## # Gets the main page for this RDoc store. This page is used as the root of # the RDoc server. def main @cache[:main] end ## # Sets the main page for this RDoc store. def main= page @cache[:main] = page end ## # Converts the variable => ClassModule map +variables+ from a C parser into # a variable => class name map. def make_variable_map variables map = {} variables.each { |variable, class_module| map[variable] = class_module.full_name } map end ## # Path to the ri data for +method_name+ in +klass_name+ def method_file klass_name, method_name method_name = method_name.split('::').last method_name =~ /#(.*)/ method_type = $1 ? 'i' : 'c' method_name = $1 if $1 method_name = method_name.gsub(/\W/) { "%%%02x" % $&[0].ord } File.join class_path(klass_name), "#{method_name}-#{method_type}.ri" end ## # Modules cache accessor. An Array of all the module (and class) names in # the store. def module_names @cache[:modules] end ## # Hash of all modules known to RDoc def modules_hash @modules_hash end ## # Returns the RDoc::TopLevel that is a text file and has the given +name+ def page name @text_files_hash.each_value.find do |file| file.page_name == name or file.base_name == name end end ## # Path to the ri data for +page_name+ def page_file page_name file_name = File.basename(page_name).gsub('.', '_') File.join @path, File.dirname(page_name), "page-#{file_name}.ri" end ## # Removes from +all_hash+ the contexts that are nodoc or have no content. # # See RDoc::Context#remove_from_documentation? def remove_nodoc all_hash all_hash.keys.each do |name| context = all_hash[name] all_hash.delete(name) if context.remove_from_documentation? end end ## # Saves all entries in the store def save load_cache all_classes_and_modules.each do |klass| save_class klass klass.each_method do |method| save_method klass, method end klass.each_attribute do |attribute| save_method klass, attribute end end all_files.each do |file| save_page file end save_cache end ## # Writes the cache file for this store def save_cache clean_cache_collection @cache[:ancestors] clean_cache_collection @cache[:attributes] clean_cache_collection @cache[:class_methods] clean_cache_collection @cache[:instance_methods] @cache[:modules].uniq! @cache[:modules].sort! @cache[:pages].uniq! @cache[:pages].sort! @cache[:encoding] = @encoding # this gets set twice due to assert_cache @cache[:c_class_variables].merge! @c_class_variables @cache[:c_singleton_class_variables].merge! @c_singleton_class_variables return if @dry_run File.open cache_path, 'wb' do |io| Marshal.dump @cache, io end end ## # Writes the ri data for +klass+ (or module) def save_class klass full_name = klass.full_name FileUtils.mkdir_p class_path(full_name) unless @dry_run @cache[:modules] << full_name path = class_file full_name begin disk_klass = load_class full_name klass = disk_klass.merge klass rescue MissingFileError end # BasicObject has no ancestors ancestors = klass.direct_ancestors.compact.map do |ancestor| # HACK for classes we don't know about (class X < RuntimeError) String === ancestor ? ancestor : ancestor.full_name end @cache[:ancestors][full_name] ||= [] @cache[:ancestors][full_name].concat ancestors attribute_definitions = klass.attributes.map do |attribute| "#{attribute.definition} #{attribute.name}" end unless attribute_definitions.empty? then @cache[:attributes][full_name] ||= [] @cache[:attributes][full_name].concat attribute_definitions end to_delete = [] unless klass.method_list.empty? then @cache[:class_methods][full_name] ||= [] @cache[:instance_methods][full_name] ||= [] class_methods, instance_methods = klass.method_list.partition { |meth| meth.singleton } class_methods = class_methods. map { |method| method.name } instance_methods = instance_methods.map { |method| method.name } attribute_names = klass.attributes.map { |attr| attr.name } old = @cache[:class_methods][full_name] - class_methods to_delete.concat old.map { |method| method_file full_name, "#{full_name}::#{method}" } old = @cache[:instance_methods][full_name] - instance_methods - attribute_names to_delete.concat old.map { |method| method_file full_name, "#{full_name}##{method}" } @cache[:class_methods][full_name] = class_methods @cache[:instance_methods][full_name] = instance_methods end return if @dry_run FileUtils.rm_f to_delete File.open path, 'wb' do |io| Marshal.dump klass, io end end ## # Writes the ri data for +method+ on +klass+ def save_method klass, method full_name = klass.full_name FileUtils.mkdir_p class_path(full_name) unless @dry_run cache = if method.singleton then @cache[:class_methods] else @cache[:instance_methods] end cache[full_name] ||= [] cache[full_name] << method.name return if @dry_run File.open method_file(full_name, method.full_name), 'wb' do |io| Marshal.dump method, io end end ## # Writes the ri data for +page+ def save_page page return unless page.text? path = page_file page.full_name FileUtils.mkdir_p File.dirname(path) unless @dry_run cache[:pages] ||= [] cache[:pages] << page.full_name return if @dry_run File.open path, 'wb' do |io| Marshal.dump page, io end end ## # Source of the contents of this store. # # For a store from a gem the source is the gem name. For a store from the # home directory the source is "home". For system ri store (the standard # library documentation) the source is"ruby". For a store from the site # ri directory the store is "site". For other stores the source is the # #path. def source case type when :gem then File.basename File.expand_path '..', @path when :home then 'home' when :site then 'site' when :system then 'ruby' else @path end end ## # Gets the title for this RDoc store. This is used as the title in each # page on the RDoc server def title @cache[:title] end ## # Sets the title page for this RDoc store. def title= title @cache[:title] = title end ## # Returns the unique classes discovered by RDoc. # # ::complete must have been called prior to using this method. def unique_classes @unique_classes end ## # Returns the unique classes and modules discovered by RDoc. # ::complete must have been called prior to using this method. def unique_classes_and_modules @unique_classes + @unique_modules end ## # Returns the unique modules discovered by RDoc. # ::complete must have been called prior to using this method. def unique_modules @unique_modules end private def marshal_load(file) File.open(file, 'rb') {|io| Marshal.load(io, MarshalFilter)} end MarshalFilter = proc do |obj| case obj when true, false, nil, Array, Class, Encoding, Hash, Integer, String, Symbol, RDoc::Text else unless obj.class.name.start_with?("RDoc::") raise TypeError, "not permitted class: #{obj.class.name}" end end obj end private_constant :MarshalFilter end PK!^t; markup.rbnu[# frozen_string_literal: true ## # RDoc::Markup parses plain text documents and attempts to decompose them into # their constituent parts. Some of these parts are high-level: paragraphs, # chunks of verbatim text, list entries and the like. Other parts happen at # the character level: a piece of bold text, a word in code font. This markup # is similar in spirit to that used on WikiWiki webs, where folks create web # pages using a simple set of formatting rules. # # RDoc::Markup and other markup formats do no output formatting, this is # handled by the RDoc::Markup::Formatter subclasses. # # = Supported Formats # # Besides the RDoc::Markup format, the following formats are built in to RDoc: # # markdown:: # The markdown format as described by # http://daringfireball.net/projects/markdown/. See RDoc::Markdown for # details on the parser and supported extensions. # rd:: # The rdtool format. See RDoc::RD for details on the parser and format. # tomdoc:: # The TomDoc format as described by http://tomdoc.org/. See RDoc::TomDoc # for details on the parser and supported extensions. # # You can choose a markup format using the following methods: # # per project:: # If you build your documentation with rake use RDoc::Task#markup. # # If you build your documentation by hand run: # # rdoc --markup your_favorite_format --write-options # # and commit .rdoc_options and ship it with your packaged gem. # per file:: # At the top of the file use the :markup: directive to set the # default format for the rest of the file. # per comment:: # Use the :markup: directive at the top of a comment you want # to write in a different format. # # = RDoc::Markup # # RDoc::Markup is extensible at runtime: you can add \new markup elements to # be recognized in the documents that RDoc::Markup parses. # # RDoc::Markup is intended to be the basis for a family of tools which share # the common requirement that simple, plain-text should be rendered in a # variety of different output formats and media. It is envisaged that # RDoc::Markup could be the basis for formatting RDoc style comment blocks, # Wiki entries, and online FAQs. # # == Synopsis # # This code converts +input_string+ to HTML. The conversion takes place in # the +convert+ method, so you can use the same RDoc::Markup converter to # convert multiple input strings. # # require 'rdoc' # # h = RDoc::Markup::ToHtml.new(RDoc::Options.new) # # puts h.convert(input_string) # # You can extend the RDoc::Markup parser to recognize new markup # sequences, and to add regexp handling. Here we make WikiWords significant to # the parser, and also make the sequences {word} and \text... signify # strike-through text. We then subclass the HTML output class to deal # with these: # # require 'rdoc' # # class WikiHtml < RDoc::Markup::ToHtml # def handle_regexp_WIKIWORD(target) # "" + target.text + "" # end # end # # markup = RDoc::Markup.new # markup.add_word_pair("{", "}", :STRIKE) # markup.add_html("no", :STRIKE) # # markup.add_regexp_handling(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD) # # wh = WikiHtml.new RDoc::Options.new, markup # wh.add_tag(:STRIKE, "", "") # # puts "#{wh.convert ARGF.read}" # # == Encoding # # Where Encoding support is available, RDoc will automatically convert all # documents to the same output encoding. The output encoding can be set via # RDoc::Options#encoding and defaults to Encoding.default_external. # # = \RDoc Markup Reference # # See RDoc::MarkupReference. # #-- # Original Author:: Dave Thomas, dave@pragmaticprogrammer.com # License:: Ruby license class RDoc::Markup ## # An AttributeManager which handles inline markup. attr_reader :attribute_manager ## # Parses +str+ into an RDoc::Markup::Document. def self.parse str RDoc::Markup::Parser.parse str rescue RDoc::Markup::Parser::Error => e $stderr.puts <<-EOF While parsing markup, RDoc encountered a #{e.class}: #{e} \tfrom #{e.backtrace.join "\n\tfrom "} ---8<--- #{text} ---8<--- RDoc #{RDoc::VERSION} Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL} #{RUBY_RELEASE_DATE} Please file a bug report with the above information at: https://github.com/ruby/rdoc/issues EOF raise end ## # Take a block of text and use various heuristics to determine its # structure (paragraphs, lists, and so on). Invoke an event handler as we # identify significant chunks. def initialize attribute_manager = nil @attribute_manager = attribute_manager || RDoc::Markup::AttributeManager.new @output = nil end ## # Add to the sequences used to add formatting to an individual word (such # as *bold*). Matching entries will generate attributes that the output # formatters can recognize by their +name+. def add_word_pair(start, stop, name) @attribute_manager.add_word_pair(start, stop, name) end ## # Add to the sequences recognized as general markup. def add_html(tag, name) @attribute_manager.add_html(tag, name) end ## # Add to other inline sequences. For example, we could add WikiWords using # something like: # # parser.add_regexp_handling(/\b([A-Z][a-z]+[A-Z]\w+)/, :WIKIWORD) # # Each wiki word will be presented to the output formatter. def add_regexp_handling(pattern, name) @attribute_manager.add_regexp_handling(pattern, name) end ## # We take +input+, parse it if necessary, then invoke the output +formatter+ # using a Visitor to render the result. def convert input, formatter document = case input when RDoc::Markup::Document then input else RDoc::Markup::Parser.parse input end document.accept formatter end autoload :Parser, "#{__dir__}/markup/parser" autoload :PreProcess, "#{__dir__}/markup/pre_process" # Inline markup classes autoload :AttrChanger, "#{__dir__}/markup/attr_changer" autoload :AttrSpan, "#{__dir__}/markup/attr_span" autoload :Attributes, "#{__dir__}/markup/attributes" autoload :AttributeManager, "#{__dir__}/markup/attribute_manager" autoload :RegexpHandling, "#{__dir__}/markup/regexp_handling" # RDoc::Markup AST autoload :BlankLine, "#{__dir__}/markup/blank_line" autoload :BlockQuote, "#{__dir__}/markup/block_quote" autoload :Document, "#{__dir__}/markup/document" autoload :HardBreak, "#{__dir__}/markup/hard_break" autoload :Heading, "#{__dir__}/markup/heading" autoload :Include, "#{__dir__}/markup/include" autoload :IndentedParagraph, "#{__dir__}/markup/indented_paragraph" autoload :List, "#{__dir__}/markup/list" autoload :ListItem, "#{__dir__}/markup/list_item" autoload :Paragraph, "#{__dir__}/markup/paragraph" autoload :Table, "#{__dir__}/markup/table" autoload :Raw, "#{__dir__}/markup/raw" autoload :Rule, "#{__dir__}/markup/rule" autoload :Verbatim, "#{__dir__}/markup/verbatim" # Formatters autoload :Formatter, "#{__dir__}/markup/formatter" autoload :ToAnsi, "#{__dir__}/markup/to_ansi" autoload :ToBs, "#{__dir__}/markup/to_bs" autoload :ToHtml, "#{__dir__}/markup/to_html" autoload :ToHtmlCrossref, "#{__dir__}/markup/to_html_crossref" autoload :ToHtmlSnippet, "#{__dir__}/markup/to_html_snippet" autoload :ToLabel, "#{__dir__}/markup/to_label" autoload :ToMarkdown, "#{__dir__}/markup/to_markdown" autoload :ToRdoc, "#{__dir__}/markup/to_rdoc" autoload :ToTableOfContents, "#{__dir__}/markup/to_table_of_contents" autoload :ToTest, "#{__dir__}/markup/to_test" autoload :ToTtOnly, "#{__dir__}/markup/to_tt_only" end PK!vTDODOclass_module.rbnu[# 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 attr_accessor :diagram # :nodoc: ## # 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.viewer = mod.viewer 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 = [] @diagram = nil @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 update_includes 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 ## # 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] @comment = array[4] @comment_location = if RDoc::Markup::Document === @comment.parts.first then @comment else RDoc::Markup::Document.new @comment end array[5].each do |name, rw, visibility, singleton, file| singleton ||= false visibility ||= :public attr = RDoc::Attr.new nil, name, rw, nil, singleton add_attribute attr attr.visibility = visibility attr.record_location RDoc::TopLevel.new file end array[6].each do |constant, comment, file| case constant when RDoc::Constant then add_constant constant else constant = add_constant RDoc::Constant.new(constant, nil, comment) constant.record_location RDoc::TopLevel.new file end end array[7].each do |name, comment, file| incl = add_include RDoc::Include.new(name, comment) 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 method.singleton = true if type == 'class' method.record_location RDoc::TopLevel.new file add_method method end end end array[9].each do |name, comment, file| ext = add_extend RDoc::Extend.new(name, comment) 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 = @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 http_url @store.rdoc.generator.class_dir 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+ def superclass=(superclass) raise NoMethodError, "#{full_name} is a module" if module? @superclass = superclass 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 end PK!KK generator.rbnu[# 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 PK!/ include.rbnu[# frozen_string_literal: true ## # A Module included in a class with \#include # # RDoc::Include.new 'Enumerable', 'comment ...' class RDoc::Include < RDoc::Mixin end PK! extend.rbnu[# frozen_string_literal: true ## # A Module extension to a class with \#extend # # RDoc::Extend.new 'Enumerable', 'comment ...' class RDoc::Extend < RDoc::Mixin end PK!Pn markdown.rbnu[# coding: UTF-8 # frozen_string_literal: true # :markup: markdown ## # RDoc::Markdown as described by the [markdown syntax][syntax]. # # To choose Markdown as your only default format see # RDoc::Options@Saved+Options for instructions on setting up a `.doc_options` # file to store your project default. # # ## Usage # # Here is a brief example of using this parse to read a markdown file by hand. # # data = File.read("README.md") # formatter = RDoc::Markup::ToHtml.new(RDoc::Options.new, nil) # html = RDoc::Markdown.parse(data).accept(formatter) # # # do something with html # # ## Extensions # # The following markdown extensions are supported by the parser, but not all # are used in RDoc output by default. # # ### RDoc # # The RDoc Markdown parser has the following built-in behaviors that cannot be # disabled. # # Underscores embedded in words are never interpreted as emphasis. (While the # [markdown dingus][dingus] emphasizes in-word underscores, neither the # Markdown syntax nor MarkdownTest mention this behavior.) # # For HTML output, RDoc always auto-links bare URLs. # # ### Break on Newline # # The break_on_newline extension converts all newlines into hard line breaks # as in [Github Flavored Markdown][GFM]. This extension is disabled by # default. # # ### CSS # # The #css extension enables CSS blocks to be included in the output, but they # are not used for any built-in RDoc output format. This extension is disabled # by default. # # Example: # # # # ### Definition Lists # # The definition_lists extension allows definition lists using the [PHP # Markdown Extra syntax][PHPE], but only one label and definition are supported # at this time. This extension is enabled by default. # # Example: # # ``` # cat # : A small furry mammal # that seems to sleep a lot # # ant # : A little insect that is known # to enjoy picnics # # ``` # # Produces: # # cat # : A small furry mammal # that seems to sleep a lot # # ant # : A little insect that is known # to enjoy picnics # # ### Strike # # Example: # # ``` # This is ~~striked~~. # ``` # # Produces: # # This is ~~striked~~. # # ### Github # # The #github extension enables a partial set of [Github Flavored Markdown] # [GFM]. This extension is enabled by default. # # Supported github extensions include: # # #### Fenced code blocks # # Use ` ``` ` around a block of code instead of indenting it four spaces. # # #### Syntax highlighting # # Use ` ``` ruby ` as the start of a code fence to add syntax highlighting. # (Currently only `ruby` syntax is supported). # # ### HTML # # Enables raw HTML to be included in the output. This extension is enabled by # default. # # Example: # # # ... #
    # # ### Notes # # The #notes extension enables footnote support. This extension is enabled by # default. # # Example: # # Here is some text[^1] including an inline footnote ^[for short footnotes] # # ... # # [^1]: With the footnote text down at the bottom # # Produces: # # Here is some text[^1] including an inline footnote ^[for short footnotes] # # [^1]: With the footnote text down at the bottom # # ## Limitations # # * Link titles are not used # * Footnotes are collapsed into a single paragraph # # ## Author # # This markdown parser is a port to kpeg from [peg-markdown][pegmarkdown] by # John MacFarlane. # # It is used under the 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. # # The port to kpeg was performed by Eric Hodel and Evan Phoenix # # [dingus]: http://daringfireball.net/projects/markdown/dingus # [GFM]: https://github.github.com/gfm/ # [pegmarkdown]: https://github.com/jgm/peg-markdown # [PHPE]: http://michelf.com/projects/php-markdown/extra/#def-list # [syntax]: http://daringfireball.net/projects/markdown/syntax #-- # Last updated to jgm/peg-markdown commit 8f8fc22ef0 class RDoc::Markdown # :stopdoc: # This is distinct from setup_parser so that a standalone parser # can redefine #initialize and still have access to the proper # parser setup code. def initialize(str, debug=false) setup_parser(str, debug) end # Prepares for parsing +str+. If you define a custom initialize you must # call this method before #parse def setup_parser(str, debug=false) set_string str, 0 @memoizations = Hash.new { |h,k| h[k] = {} } @result = nil @failed_rule = nil @failing_rule_offset = -1 @line_offsets = nil setup_foreign_grammar end attr_reader :string attr_reader :failing_rule_offset attr_accessor :result, :pos def current_column(target=pos) if string[target] == "\n" && (c = string.rindex("\n", target-1) || -1) return target - c elsif c = string.rindex("\n", target) return target - c end target + 1 end def position_line_offsets unless @position_line_offsets @position_line_offsets = [] total = 0 string.each_line do |line| total += line.size @position_line_offsets << total end end @position_line_offsets end if [].respond_to? :bsearch_index def current_line(target=pos) if line = position_line_offsets.bsearch_index {|x| x > target } return line + 1 end raise "Target position #{target} is outside of string" end else def current_line(target=pos) if line = position_line_offsets.index {|x| x > target } return line + 1 end raise "Target position #{target} is outside of string" end end def current_character(target=pos) if target < 0 || target >= string.size raise "Target position #{target} is outside of string" end string[target, 1] end KpegPosInfo = Struct.new(:pos, :lno, :col, :line, :char) def current_pos_info(target=pos) l = current_line target c = current_column target ln = get_line(l-1) chr = string[target,1] KpegPosInfo.new(target, l, c, ln, chr) end def lines string.lines end def get_line(no) loff = position_line_offsets if no < 0 raise "Line No is out of range: #{no} < 0" elsif no >= loff.size raise "Line No is out of range: #{no} >= #{loff.size}" end lend = loff[no]-1 lstart = no > 0 ? loff[no-1] : 0 string[lstart..lend] end def get_text(start) @string[start..@pos-1] end # Sets the string and current parsing position for the parser. def set_string string, pos @string = string @string_size = string ? string.size : 0 @pos = pos @position_line_offsets = nil end def show_pos width = 10 if @pos < width "#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")" else "#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")" end end def failure_info l = current_line @failing_rule_offset c = current_column @failing_rule_offset if @failed_rule.kind_of? Symbol info = self.class::Rules[@failed_rule] "line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'" else "line #{l}, column #{c}: failed rule '#{@failed_rule}'" end end def failure_caret p = current_pos_info @failing_rule_offset "#{p.line.chomp}\n#{' ' * (p.col - 1)}^" end def failure_character current_character @failing_rule_offset end def failure_oneline p = current_pos_info @failing_rule_offset if @failed_rule.kind_of? Symbol info = self.class::Rules[@failed_rule] "@#{p.lno}:#{p.col} failed rule '#{info.name}', got '#{p.char}'" else "@#{p.lno}:#{p.col} failed rule '#{@failed_rule}', got '#{p.char}'" end end class ParseError < RuntimeError end def raise_error raise ParseError, failure_oneline end def show_error(io=STDOUT) error_pos = @failing_rule_offset p = current_pos_info(error_pos) io.puts "On line #{p.lno}, column #{p.col}:" if @failed_rule.kind_of? Symbol info = self.class::Rules[@failed_rule] io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')" else io.puts "Failed to match rule '#{@failed_rule}'" end io.puts "Got: #{p.char.inspect}" io.puts "=> #{p.line}" io.print(" " * (p.col + 2)) io.puts "^" end def set_failed_rule(name) if @pos > @failing_rule_offset @failed_rule = name @failing_rule_offset = @pos end end attr_reader :failed_rule def match_string(str) len = str.size if @string[pos,len] == str @pos += len return str end return nil end def scan(reg) if m = reg.match(@string, @pos) @pos = m.end(0) return true end return nil end if "".respond_to? :ord def get_byte if @pos >= @string_size return nil end s = @string[@pos].ord @pos += 1 s end else def get_byte if @pos >= @string_size return nil end s = @string[@pos] @pos += 1 s end end def parse(rule=nil) # We invoke the rules indirectly via apply # instead of by just calling them as methods because # if the rules use left recursion, apply needs to # manage that. if !rule apply(:_root) else method = rule.gsub("-","_hyphen_") apply :"_#{method}" end end class MemoEntry def initialize(ans, pos) @ans = ans @pos = pos @result = nil @set = false @left_rec = false end attr_reader :ans, :pos, :result, :set attr_accessor :left_rec def move!(ans, pos, result) @ans = ans @pos = pos @result = result @set = true @left_rec = false end end def external_invoke(other, rule, *args) old_pos = @pos old_string = @string set_string other.string, other.pos begin if val = __send__(rule, *args) other.pos = @pos other.result = @result else other.set_failed_rule "#{self.class}##{rule}" end val ensure set_string old_string, old_pos end end def apply_with_args(rule, *args) @result = nil memo_key = [rule, args] if m = @memoizations[memo_key][@pos] @pos = m.pos if !m.set m.left_rec = true return nil end @result = m.result return m.ans else m = MemoEntry.new(nil, @pos) @memoizations[memo_key][@pos] = m start_pos = @pos ans = __send__ rule, *args lr = m.left_rec m.move! ans, @pos, @result # Don't bother trying to grow the left recursion # if it's failing straight away (thus there is no seed) if ans and lr return grow_lr(rule, args, start_pos, m) else return ans end end end def apply(rule) @result = nil if m = @memoizations[rule][@pos] @pos = m.pos if !m.set m.left_rec = true return nil end @result = m.result return m.ans else m = MemoEntry.new(nil, @pos) @memoizations[rule][@pos] = m start_pos = @pos ans = __send__ rule lr = m.left_rec m.move! ans, @pos, @result # Don't bother trying to grow the left recursion # if it's failing straight away (thus there is no seed) if ans and lr return grow_lr(rule, nil, start_pos, m) else return ans end end end def grow_lr(rule, args, start_pos, m) while true @pos = start_pos @result = m.result if args ans = __send__ rule, *args else ans = __send__ rule end return nil unless ans break if @pos <= m.pos m.move! ans, @pos, @result end @result = m.result @pos = m.pos return m.ans end class RuleInfo def initialize(name, rendered) @name = name @rendered = rendered end attr_reader :name, :rendered end def self.rule_info(name, rendered) RuleInfo.new(name, rendered) end # :startdoc: require_relative '../rdoc' require_relative 'markup/to_joined_paragraph' require_relative 'markdown/entities' require_relative 'markdown/literals' ## # Supported extensions EXTENSIONS = [] ## # Extensions enabled by default DEFAULT_EXTENSIONS = [ :definition_lists, :github, :html, :notes, :strike, ] # :section: Extensions ## # Creates extension methods for the `name` extension to enable and disable # the extension and to query if they are active. def self.extension name EXTENSIONS << name define_method "#{name}?" do extension? name end define_method "#{name}=" do |enable| extension name, enable end end ## # Converts all newlines into hard breaks extension :break_on_newline ## # Allow style blocks extension :css ## # Allow PHP Markdown Extras style definition lists extension :definition_lists ## # Allow Github Flavored Markdown extension :github ## # Allow HTML extension :html ## # Enables the notes extension extension :notes ## # Enables the strike extension extension :strike # :section: ## # Parses the `markdown` document into an RDoc::Document using the default # extensions. def self.parse markdown parser = new parser.parse markdown end # TODO remove when kpeg 0.10 is released alias orig_initialize initialize # :nodoc: ## # Creates a new markdown parser that enables the given +extensions+. def initialize extensions = DEFAULT_EXTENSIONS, debug = false @debug = debug @formatter = RDoc::Markup::ToJoinedParagraph.new @extensions = extensions @references = nil @unlinked_references = nil @footnotes = nil @note_order = nil end ## # Wraps `text` in emphasis for rdoc inline formatting def emphasis text if text =~ /\A[a-z\d.\/]+\z/i then "_#{text}_" else "#{text}" end end ## # :category: Extensions # # Is the extension `name` enabled? def extension? name @extensions.include? name end ## # :category: Extensions # # Enables or disables the extension with `name` def extension name, enable if enable then @extensions |= [name] else @extensions -= [name] end end ## # Parses `text` in a clone of this parser. This is used for handling nested # lists the same way as markdown_parser. def inner_parse text # :nodoc: parser = clone parser.setup_parser text, @debug parser.peg_parse doc = parser.result doc.accept @formatter doc.parts end ## # Finds a link reference for `label` and creates a new link to it with # `content` as the link text. If `label` was not encountered in the # reference-gathering parser pass the label and content are reconstructed # with the linking `text` (usually whitespace). def link_to content, label = content, text = nil raise ParseError, 'enable notes extension' if content.start_with? '^' and label.equal? content if ref = @references[label] then "{#{content}}[#{ref}]" elsif label.equal? content then "[#{content}]#{text}" else "[#{content}]#{text}[#{label}]" end end ## # Creates an RDoc::Markup::ListItem by parsing the `unparsed` content from # the first parsing pass. def list_item_from unparsed parsed = inner_parse unparsed.join RDoc::Markup::ListItem.new nil, *parsed end ## # Stores `label` as a note and fills in previously unknown note references. def note label #foottext = "rdoc-label:foottext-#{label}:footmark-#{label}" #ref.replace foottext if ref = @unlinked_notes.delete(label) @notes[label] = foottext #"{^1}[rdoc-label:footmark-#{label}:foottext-#{label}] " end ## # Creates a new link for the footnote `reference` and adds the reference to # the note order list for proper display at the end of the document. def note_for ref @note_order << ref label = @note_order.length "{*#{label}}[rdoc-label:foottext-#{label}:footmark-#{label}]" end ## # The internal kpeg parse method alias peg_parse parse # :nodoc: ## # Creates an RDoc::Markup::Paragraph from `parts` and including # extension-specific behavior def paragraph parts parts = parts.map do |part| if "\n" == part then RDoc::Markup::HardBreak.new else part end end if break_on_newline? RDoc::Markup::Paragraph.new(*parts) end ## # Parses `markdown` into an RDoc::Document def parse markdown @references = {} @unlinked_references = {} markdown += "\n\n" setup_parser markdown, @debug peg_parse 'References' if notes? then @footnotes = {} setup_parser markdown, @debug peg_parse 'Notes' # using note_order on the first pass would be a bug @note_order = [] end setup_parser markdown, @debug peg_parse doc = result if notes? and not @footnotes.empty? then doc << RDoc::Markup::Rule.new(1) @note_order.each_with_index do |ref, index| label = index + 1 note = @footnotes[ref] or raise ParseError, "footnote [^#{ref}] not found" link = "{^#{label}}[rdoc-label:footmark-#{label}:foottext-#{label}] " note.parts.unshift link doc << note end end doc.accept @formatter doc end ## # Stores `label` as a reference to `link` and fills in previously unknown # link references. def reference label, link if ref = @unlinked_references.delete(label) then ref.replace link end @references[label] = link end ## # Wraps `text` in strong markup for rdoc inline formatting def strong text if text =~ /\A[a-z\d.\/-]+\z/i then "*#{text}*" else "#{text}" end end ## # Wraps `text` in strike markup for rdoc inline formatting def strike text if text =~ /\A[a-z\d.\/-]+\z/i then "~#{text}~" else "#{text}" end end # :stopdoc: def setup_foreign_grammar @_grammar_literals = RDoc::Markdown::Literals.new(nil) end # root = Doc def _root _tmp = apply(:_Doc) set_failed_rule :_root unless _tmp return _tmp end # Doc = BOM? Block*:a { RDoc::Markup::Document.new(*a.compact) } def _Doc _save = self.pos while true # sequence _save1 = self.pos _tmp = apply(:_BOM) unless _tmp _tmp = true self.pos = _save1 end unless _tmp self.pos = _save break end _ary = [] while true _tmp = apply(:_Block) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary a = @result unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::Document.new(*a.compact) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Doc unless _tmp return _tmp end # Block = @BlankLine* (BlockQuote | Verbatim | CodeFence | Table | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain) def _Block _save = self.pos while true # sequence while true _tmp = _BlankLine() break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _save2 = self.pos while true # choice _tmp = apply(:_BlockQuote) break if _tmp self.pos = _save2 _tmp = apply(:_Verbatim) break if _tmp self.pos = _save2 _tmp = apply(:_CodeFence) break if _tmp self.pos = _save2 _tmp = apply(:_Table) break if _tmp self.pos = _save2 _tmp = apply(:_Note) break if _tmp self.pos = _save2 _tmp = apply(:_Reference) break if _tmp self.pos = _save2 _tmp = apply(:_HorizontalRule) break if _tmp self.pos = _save2 _tmp = apply(:_Heading) break if _tmp self.pos = _save2 _tmp = apply(:_OrderedList) break if _tmp self.pos = _save2 _tmp = apply(:_BulletList) break if _tmp self.pos = _save2 _tmp = apply(:_DefinitionList) break if _tmp self.pos = _save2 _tmp = apply(:_HtmlBlock) break if _tmp self.pos = _save2 _tmp = apply(:_StyleBlock) break if _tmp self.pos = _save2 _tmp = apply(:_Para) break if _tmp self.pos = _save2 _tmp = apply(:_Plain) break if _tmp self.pos = _save2 break end # end choice unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Block unless _tmp return _tmp end # Para = @NonindentSpace Inlines:a @BlankLine+ { paragraph a } def _Para _save = self.pos while true # sequence _tmp = _NonindentSpace() unless _tmp self.pos = _save break end _tmp = apply(:_Inlines) a = @result unless _tmp self.pos = _save break end _save1 = self.pos _tmp = _BlankLine() if _tmp while true _tmp = _BlankLine() break unless _tmp end _tmp = true else self.pos = _save1 end unless _tmp self.pos = _save break end @result = begin; paragraph a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Para unless _tmp return _tmp end # Plain = Inlines:a { paragraph a } def _Plain _save = self.pos while true # sequence _tmp = apply(:_Inlines) a = @result unless _tmp self.pos = _save break end @result = begin; paragraph a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Plain unless _tmp return _tmp end # AtxInline = !@Newline !(@Sp /#*/ @Sp @Newline) Inline def _AtxInline _save = self.pos while true # sequence _save1 = self.pos _tmp = _Newline() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save3 break end _tmp = scan(/\G(?-mix:#*)/) unless _tmp self.pos = _save3 break end _tmp = _Sp() unless _tmp self.pos = _save3 break end _tmp = _Newline() unless _tmp self.pos = _save3 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save2 unless _tmp self.pos = _save break end _tmp = apply(:_Inline) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_AtxInline unless _tmp return _tmp end # AtxStart = < /\#{1,6}/ > { text.length } def _AtxStart _save = self.pos while true # sequence _text_start = self.pos _tmp = scan(/\G(?-mix:\#{1,6})/) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; text.length ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_AtxStart unless _tmp return _tmp end # AtxHeading = AtxStart:s @Sp AtxInline+:a (@Sp /#*/ @Sp)? @Newline { RDoc::Markup::Heading.new(s, a.join) } def _AtxHeading _save = self.pos while true # sequence _tmp = apply(:_AtxStart) s = @result unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end _save1 = self.pos _ary = [] _tmp = apply(:_AtxInline) if _tmp _ary << @result while true _tmp = apply(:_AtxInline) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save1 end a = @result unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save3 break end _tmp = scan(/\G(?-mix:#*)/) unless _tmp self.pos = _save3 break end _tmp = _Sp() unless _tmp self.pos = _save3 end break end # end sequence unless _tmp _tmp = true self.pos = _save2 end unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::Heading.new(s, a.join) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_AtxHeading unless _tmp return _tmp end # SetextHeading = (SetextHeading1 | SetextHeading2) def _SetextHeading _save = self.pos while true # choice _tmp = apply(:_SetextHeading1) break if _tmp self.pos = _save _tmp = apply(:_SetextHeading2) break if _tmp self.pos = _save break end # end choice set_failed_rule :_SetextHeading unless _tmp return _tmp end # SetextBottom1 = /={1,}/ @Newline def _SetextBottom1 _save = self.pos while true # sequence _tmp = scan(/\G(?-mix:={1,})/) unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_SetextBottom1 unless _tmp return _tmp end # SetextBottom2 = /-{1,}/ @Newline def _SetextBottom2 _save = self.pos while true # sequence _tmp = scan(/\G(?-mix:-{1,})/) unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_SetextBottom2 unless _tmp return _tmp end # SetextHeading1 = &(@RawLine SetextBottom1) @StartList:a (!@Endline Inline:b { a << b })+ @Sp @Newline SetextBottom1 { RDoc::Markup::Heading.new(1, a.join) } def _SetextHeading1 _save = self.pos while true # sequence _save1 = self.pos _save2 = self.pos while true # sequence _tmp = _RawLine() unless _tmp self.pos = _save2 break end _tmp = apply(:_SetextBottom1) unless _tmp self.pos = _save2 end break end # end sequence self.pos = _save1 unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save3 = self.pos _save4 = self.pos while true # sequence _save5 = self.pos _tmp = _Endline() _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save4 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save4 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save4 end break end # end sequence if _tmp while true _save6 = self.pos while true # sequence _save7 = self.pos _tmp = _Endline() _tmp = _tmp ? nil : true self.pos = _save7 unless _tmp self.pos = _save6 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save6 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save6 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save3 end unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end _tmp = apply(:_SetextBottom1) unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::Heading.new(1, a.join) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_SetextHeading1 unless _tmp return _tmp end # SetextHeading2 = &(@RawLine SetextBottom2) @StartList:a (!@Endline Inline:b { a << b })+ @Sp @Newline SetextBottom2 { RDoc::Markup::Heading.new(2, a.join) } def _SetextHeading2 _save = self.pos while true # sequence _save1 = self.pos _save2 = self.pos while true # sequence _tmp = _RawLine() unless _tmp self.pos = _save2 break end _tmp = apply(:_SetextBottom2) unless _tmp self.pos = _save2 end break end # end sequence self.pos = _save1 unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save3 = self.pos _save4 = self.pos while true # sequence _save5 = self.pos _tmp = _Endline() _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save4 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save4 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save4 end break end # end sequence if _tmp while true _save6 = self.pos while true # sequence _save7 = self.pos _tmp = _Endline() _tmp = _tmp ? nil : true self.pos = _save7 unless _tmp self.pos = _save6 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save6 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save6 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save3 end unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end _tmp = apply(:_SetextBottom2) unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::Heading.new(2, a.join) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_SetextHeading2 unless _tmp return _tmp end # Heading = (SetextHeading | AtxHeading) def _Heading _save = self.pos while true # choice _tmp = apply(:_SetextHeading) break if _tmp self.pos = _save _tmp = apply(:_AtxHeading) break if _tmp self.pos = _save break end # end choice set_failed_rule :_Heading unless _tmp return _tmp end # BlockQuote = BlockQuoteRaw:a { RDoc::Markup::BlockQuote.new(*a) } def _BlockQuote _save = self.pos while true # sequence _tmp = apply(:_BlockQuoteRaw) a = @result unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::BlockQuote.new(*a) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_BlockQuote unless _tmp return _tmp end # BlockQuoteRaw = @StartList:a (">" " "? Line:l { a << l } (!">" !@BlankLine Line:c { a << c })* (@BlankLine:n { a << n })*)+ { inner_parse a.join } def _BlockQuoteRaw _save = self.pos while true # sequence _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save1 = self.pos _save2 = self.pos while true # sequence _tmp = match_string(">") unless _tmp self.pos = _save2 break end _save3 = self.pos _tmp = match_string(" ") unless _tmp _tmp = true self.pos = _save3 end unless _tmp self.pos = _save2 break end _tmp = apply(:_Line) l = @result unless _tmp self.pos = _save2 break end @result = begin; a << l ; end _tmp = true unless _tmp self.pos = _save2 break end while true _save5 = self.pos while true # sequence _save6 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save5 break end _save7 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save7 unless _tmp self.pos = _save5 break end _tmp = apply(:_Line) c = @result unless _tmp self.pos = _save5 break end @result = begin; a << c ; end _tmp = true unless _tmp self.pos = _save5 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save2 break end while true _save9 = self.pos while true # sequence _tmp = _BlankLine() n = @result unless _tmp self.pos = _save9 break end @result = begin; a << n ; end _tmp = true unless _tmp self.pos = _save9 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save2 end break end # end sequence if _tmp while true _save10 = self.pos while true # sequence _tmp = match_string(">") unless _tmp self.pos = _save10 break end _save11 = self.pos _tmp = match_string(" ") unless _tmp _tmp = true self.pos = _save11 end unless _tmp self.pos = _save10 break end _tmp = apply(:_Line) l = @result unless _tmp self.pos = _save10 break end @result = begin; a << l ; end _tmp = true unless _tmp self.pos = _save10 break end while true _save13 = self.pos while true # sequence _save14 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save14 unless _tmp self.pos = _save13 break end _save15 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save15 unless _tmp self.pos = _save13 break end _tmp = apply(:_Line) c = @result unless _tmp self.pos = _save13 break end @result = begin; a << c ; end _tmp = true unless _tmp self.pos = _save13 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save10 break end while true _save17 = self.pos while true # sequence _tmp = _BlankLine() n = @result unless _tmp self.pos = _save17 break end @result = begin; a << n ; end _tmp = true unless _tmp self.pos = _save17 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save10 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save1 end unless _tmp self.pos = _save break end @result = begin; inner_parse a.join ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_BlockQuoteRaw unless _tmp return _tmp end # NonblankIndentedLine = !@BlankLine IndentedLine def _NonblankIndentedLine _save = self.pos while true # sequence _save1 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _tmp = apply(:_IndentedLine) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_NonblankIndentedLine unless _tmp return _tmp end # VerbatimChunk = @BlankLine*:a NonblankIndentedLine+:b { a.concat b } def _VerbatimChunk _save = self.pos while true # sequence _ary = [] while true _tmp = _BlankLine() _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary a = @result unless _tmp self.pos = _save break end _save2 = self.pos _ary = [] _tmp = apply(:_NonblankIndentedLine) if _tmp _ary << @result while true _tmp = apply(:_NonblankIndentedLine) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save2 end b = @result unless _tmp self.pos = _save break end @result = begin; a.concat b ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_VerbatimChunk unless _tmp return _tmp end # Verbatim = VerbatimChunk+:a { RDoc::Markup::Verbatim.new(*a.flatten) } def _Verbatim _save = self.pos while true # sequence _save1 = self.pos _ary = [] _tmp = apply(:_VerbatimChunk) if _tmp _ary << @result while true _tmp = apply(:_VerbatimChunk) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save1 end a = @result unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::Verbatim.new(*a.flatten) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Verbatim unless _tmp return _tmp end # HorizontalRule = @NonindentSpace ("*" @Sp "*" @Sp "*" (@Sp "*")* | "-" @Sp "-" @Sp "-" (@Sp "-")* | "_" @Sp "_" @Sp "_" (@Sp "_")*) @Sp @Newline @BlankLine+ { RDoc::Markup::Rule.new 1 } def _HorizontalRule _save = self.pos while true # sequence _tmp = _NonindentSpace() unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _save2 = self.pos while true # sequence _tmp = match_string("*") unless _tmp self.pos = _save2 break end _tmp = _Sp() unless _tmp self.pos = _save2 break end _tmp = match_string("*") unless _tmp self.pos = _save2 break end _tmp = _Sp() unless _tmp self.pos = _save2 break end _tmp = match_string("*") unless _tmp self.pos = _save2 break end while true _save4 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save4 break end _tmp = match_string("*") unless _tmp self.pos = _save4 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save2 end break end # end sequence break if _tmp self.pos = _save1 _save5 = self.pos while true # sequence _tmp = match_string("-") unless _tmp self.pos = _save5 break end _tmp = _Sp() unless _tmp self.pos = _save5 break end _tmp = match_string("-") unless _tmp self.pos = _save5 break end _tmp = _Sp() unless _tmp self.pos = _save5 break end _tmp = match_string("-") unless _tmp self.pos = _save5 break end while true _save7 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save7 break end _tmp = match_string("-") unless _tmp self.pos = _save7 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save5 end break end # end sequence break if _tmp self.pos = _save1 _save8 = self.pos while true # sequence _tmp = match_string("_") unless _tmp self.pos = _save8 break end _tmp = _Sp() unless _tmp self.pos = _save8 break end _tmp = match_string("_") unless _tmp self.pos = _save8 break end _tmp = _Sp() unless _tmp self.pos = _save8 break end _tmp = match_string("_") unless _tmp self.pos = _save8 break end while true _save10 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save10 break end _tmp = match_string("_") unless _tmp self.pos = _save10 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save8 end break end # end sequence break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end _save11 = self.pos _tmp = _BlankLine() if _tmp while true _tmp = _BlankLine() break unless _tmp end _tmp = true else self.pos = _save11 end unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::Rule.new 1 ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HorizontalRule unless _tmp return _tmp end # Bullet = !HorizontalRule @NonindentSpace /[+*-]/ @Spacechar+ def _Bullet _save = self.pos while true # sequence _save1 = self.pos _tmp = apply(:_HorizontalRule) _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _tmp = _NonindentSpace() unless _tmp self.pos = _save break end _tmp = scan(/\G(?-mix:[+*-])/) unless _tmp self.pos = _save break end _save2 = self.pos _tmp = _Spacechar() if _tmp while true _tmp = _Spacechar() break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Bullet unless _tmp return _tmp end # BulletList = &Bullet (ListTight | ListLoose):a { RDoc::Markup::List.new(:BULLET, *a) } def _BulletList _save = self.pos while true # sequence _save1 = self.pos _tmp = apply(:_Bullet) self.pos = _save1 unless _tmp self.pos = _save break end _save2 = self.pos while true # choice _tmp = apply(:_ListTight) break if _tmp self.pos = _save2 _tmp = apply(:_ListLoose) break if _tmp self.pos = _save2 break end # end choice a = @result unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::List.new(:BULLET, *a) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_BulletList unless _tmp return _tmp end # ListTight = ListItemTight+:a @BlankLine* !(Bullet | Enumerator) { a } def _ListTight _save = self.pos while true # sequence _save1 = self.pos _ary = [] _tmp = apply(:_ListItemTight) if _tmp _ary << @result while true _tmp = apply(:_ListItemTight) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save1 end a = @result unless _tmp self.pos = _save break end while true _tmp = _BlankLine() break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _save3 = self.pos _save4 = self.pos while true # choice _tmp = apply(:_Bullet) break if _tmp self.pos = _save4 _tmp = apply(:_Enumerator) break if _tmp self.pos = _save4 break end # end choice _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save break end @result = begin; a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ListTight unless _tmp return _tmp end # ListLoose = @StartList:a (ListItem:b @BlankLine* { a << b })+ { a } def _ListLoose _save = self.pos while true # sequence _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save1 = self.pos _save2 = self.pos while true # sequence _tmp = apply(:_ListItem) b = @result unless _tmp self.pos = _save2 break end while true _tmp = _BlankLine() break unless _tmp end _tmp = true unless _tmp self.pos = _save2 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save2 end break end # end sequence if _tmp while true _save4 = self.pos while true # sequence _tmp = apply(:_ListItem) b = @result unless _tmp self.pos = _save4 break end while true _tmp = _BlankLine() break unless _tmp end _tmp = true unless _tmp self.pos = _save4 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save4 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save1 end unless _tmp self.pos = _save break end @result = begin; a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ListLoose unless _tmp return _tmp end # ListItem = (Bullet | Enumerator) @StartList:a ListBlock:b { a << b } (ListContinuationBlock:c { a.push(*c) })* { list_item_from a } def _ListItem _save = self.pos while true # sequence _save1 = self.pos while true # choice _tmp = apply(:_Bullet) break if _tmp self.pos = _save1 _tmp = apply(:_Enumerator) break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _tmp = apply(:_ListBlock) b = @result unless _tmp self.pos = _save break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save break end while true _save3 = self.pos while true # sequence _tmp = apply(:_ListContinuationBlock) c = @result unless _tmp self.pos = _save3 break end @result = begin; a.push(*c) ; end _tmp = true unless _tmp self.pos = _save3 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end @result = begin; list_item_from a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ListItem unless _tmp return _tmp end # ListItemTight = (Bullet | Enumerator) ListBlock:a (!@BlankLine ListContinuationBlock:b { a.push(*b) })* !ListContinuationBlock { list_item_from a } def _ListItemTight _save = self.pos while true # sequence _save1 = self.pos while true # choice _tmp = apply(:_Bullet) break if _tmp self.pos = _save1 _tmp = apply(:_Enumerator) break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_ListBlock) a = @result unless _tmp self.pos = _save break end while true _save3 = self.pos while true # sequence _save4 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = apply(:_ListContinuationBlock) b = @result unless _tmp self.pos = _save3 break end @result = begin; a.push(*b) ; end _tmp = true unless _tmp self.pos = _save3 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _save5 = self.pos _tmp = apply(:_ListContinuationBlock) _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save break end @result = begin; list_item_from a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ListItemTight unless _tmp return _tmp end # ListBlock = !@BlankLine Line:a ListBlockLine*:c { [a, *c] } def _ListBlock _save = self.pos while true # sequence _save1 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _tmp = apply(:_Line) a = @result unless _tmp self.pos = _save break end _ary = [] while true _tmp = apply(:_ListBlockLine) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary c = @result unless _tmp self.pos = _save break end @result = begin; [a, *c] ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ListBlock unless _tmp return _tmp end # ListContinuationBlock = @StartList:a @BlankLine* { a << "\n" } (Indent ListBlock:b { a.concat b })+ { a } def _ListContinuationBlock _save = self.pos while true # sequence _tmp = _StartList() a = @result unless _tmp self.pos = _save break end while true _tmp = _BlankLine() break unless _tmp end _tmp = true unless _tmp self.pos = _save break end @result = begin; a << "\n" ; end _tmp = true unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # sequence _tmp = apply(:_Indent) unless _tmp self.pos = _save3 break end _tmp = apply(:_ListBlock) b = @result unless _tmp self.pos = _save3 break end @result = begin; a.concat b ; end _tmp = true unless _tmp self.pos = _save3 end break end # end sequence if _tmp while true _save4 = self.pos while true # sequence _tmp = apply(:_Indent) unless _tmp self.pos = _save4 break end _tmp = apply(:_ListBlock) b = @result unless _tmp self.pos = _save4 break end @result = begin; a.concat b ; end _tmp = true unless _tmp self.pos = _save4 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save break end @result = begin; a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ListContinuationBlock unless _tmp return _tmp end # Enumerator = @NonindentSpace [0-9]+ "." @Spacechar+ def _Enumerator _save = self.pos while true # sequence _tmp = _NonindentSpace() unless _tmp self.pos = _save break end _save1 = self.pos _save2 = self.pos _tmp = get_byte if _tmp unless _tmp >= 48 and _tmp <= 57 self.pos = _save2 _tmp = nil end end if _tmp while true _save3 = self.pos _tmp = get_byte if _tmp unless _tmp >= 48 and _tmp <= 57 self.pos = _save3 _tmp = nil end end break unless _tmp end _tmp = true else self.pos = _save1 end unless _tmp self.pos = _save break end _tmp = match_string(".") unless _tmp self.pos = _save break end _save4 = self.pos _tmp = _Spacechar() if _tmp while true _tmp = _Spacechar() break unless _tmp end _tmp = true else self.pos = _save4 end unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Enumerator unless _tmp return _tmp end # OrderedList = &Enumerator (ListTight | ListLoose):a { RDoc::Markup::List.new(:NUMBER, *a) } def _OrderedList _save = self.pos while true # sequence _save1 = self.pos _tmp = apply(:_Enumerator) self.pos = _save1 unless _tmp self.pos = _save break end _save2 = self.pos while true # choice _tmp = apply(:_ListTight) break if _tmp self.pos = _save2 _tmp = apply(:_ListLoose) break if _tmp self.pos = _save2 break end # end choice a = @result unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::List.new(:NUMBER, *a) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_OrderedList unless _tmp return _tmp end # ListBlockLine = !@BlankLine !(Indent? (Bullet | Enumerator)) !HorizontalRule OptionallyIndentedLine def _ListBlockLine _save = self.pos while true # sequence _save1 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_Indent) unless _tmp _tmp = true self.pos = _save4 end unless _tmp self.pos = _save3 break end _save5 = self.pos while true # choice _tmp = apply(:_Bullet) break if _tmp self.pos = _save5 _tmp = apply(:_Enumerator) break if _tmp self.pos = _save5 break end # end choice unless _tmp self.pos = _save3 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save2 unless _tmp self.pos = _save break end _save6 = self.pos _tmp = apply(:_HorizontalRule) _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save break end _tmp = apply(:_OptionallyIndentedLine) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ListBlockLine unless _tmp return _tmp end # HtmlOpenAnchor = "<" Spnl ("a" | "A") Spnl HtmlAttribute* ">" def _HtmlOpenAnchor _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("a") break if _tmp self.pos = _save1 _tmp = match_string("A") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlOpenAnchor unless _tmp return _tmp end # HtmlCloseAnchor = "<" Spnl "/" ("a" | "A") Spnl ">" def _HtmlCloseAnchor _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("a") break if _tmp self.pos = _save1 _tmp = match_string("A") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlCloseAnchor unless _tmp return _tmp end # HtmlAnchor = HtmlOpenAnchor (HtmlAnchor | !HtmlCloseAnchor .)* HtmlCloseAnchor def _HtmlAnchor _save = self.pos while true # sequence _tmp = apply(:_HtmlOpenAnchor) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlAnchor) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlCloseAnchor) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlCloseAnchor) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlAnchor unless _tmp return _tmp end # HtmlBlockOpenAddress = "<" Spnl ("address" | "ADDRESS") Spnl HtmlAttribute* ">" def _HtmlBlockOpenAddress _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("address") break if _tmp self.pos = _save1 _tmp = match_string("ADDRESS") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenAddress unless _tmp return _tmp end # HtmlBlockCloseAddress = "<" Spnl "/" ("address" | "ADDRESS") Spnl ">" def _HtmlBlockCloseAddress _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("address") break if _tmp self.pos = _save1 _tmp = match_string("ADDRESS") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseAddress unless _tmp return _tmp end # HtmlBlockAddress = HtmlBlockOpenAddress (HtmlBlockAddress | !HtmlBlockCloseAddress .)* HtmlBlockCloseAddress def _HtmlBlockAddress _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenAddress) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockAddress) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseAddress) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseAddress) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockAddress unless _tmp return _tmp end # HtmlBlockOpenBlockquote = "<" Spnl ("blockquote" | "BLOCKQUOTE") Spnl HtmlAttribute* ">" def _HtmlBlockOpenBlockquote _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("blockquote") break if _tmp self.pos = _save1 _tmp = match_string("BLOCKQUOTE") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenBlockquote unless _tmp return _tmp end # HtmlBlockCloseBlockquote = "<" Spnl "/" ("blockquote" | "BLOCKQUOTE") Spnl ">" def _HtmlBlockCloseBlockquote _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("blockquote") break if _tmp self.pos = _save1 _tmp = match_string("BLOCKQUOTE") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseBlockquote unless _tmp return _tmp end # HtmlBlockBlockquote = HtmlBlockOpenBlockquote (HtmlBlockBlockquote | !HtmlBlockCloseBlockquote .)* HtmlBlockCloseBlockquote def _HtmlBlockBlockquote _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenBlockquote) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockBlockquote) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseBlockquote) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseBlockquote) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockBlockquote unless _tmp return _tmp end # HtmlBlockOpenCenter = "<" Spnl ("center" | "CENTER") Spnl HtmlAttribute* ">" def _HtmlBlockOpenCenter _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("center") break if _tmp self.pos = _save1 _tmp = match_string("CENTER") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenCenter unless _tmp return _tmp end # HtmlBlockCloseCenter = "<" Spnl "/" ("center" | "CENTER") Spnl ">" def _HtmlBlockCloseCenter _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("center") break if _tmp self.pos = _save1 _tmp = match_string("CENTER") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseCenter unless _tmp return _tmp end # HtmlBlockCenter = HtmlBlockOpenCenter (HtmlBlockCenter | !HtmlBlockCloseCenter .)* HtmlBlockCloseCenter def _HtmlBlockCenter _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenCenter) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockCenter) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseCenter) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseCenter) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCenter unless _tmp return _tmp end # HtmlBlockOpenDir = "<" Spnl ("dir" | "DIR") Spnl HtmlAttribute* ">" def _HtmlBlockOpenDir _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("dir") break if _tmp self.pos = _save1 _tmp = match_string("DIR") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenDir unless _tmp return _tmp end # HtmlBlockCloseDir = "<" Spnl "/" ("dir" | "DIR") Spnl ">" def _HtmlBlockCloseDir _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("dir") break if _tmp self.pos = _save1 _tmp = match_string("DIR") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseDir unless _tmp return _tmp end # HtmlBlockDir = HtmlBlockOpenDir (HtmlBlockDir | !HtmlBlockCloseDir .)* HtmlBlockCloseDir def _HtmlBlockDir _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenDir) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockDir) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseDir) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseDir) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockDir unless _tmp return _tmp end # HtmlBlockOpenDiv = "<" Spnl ("div" | "DIV") Spnl HtmlAttribute* ">" def _HtmlBlockOpenDiv _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("div") break if _tmp self.pos = _save1 _tmp = match_string("DIV") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenDiv unless _tmp return _tmp end # HtmlBlockCloseDiv = "<" Spnl "/" ("div" | "DIV") Spnl ">" def _HtmlBlockCloseDiv _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("div") break if _tmp self.pos = _save1 _tmp = match_string("DIV") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseDiv unless _tmp return _tmp end # HtmlBlockDiv = HtmlBlockOpenDiv (HtmlBlockDiv | !HtmlBlockCloseDiv .)* HtmlBlockCloseDiv def _HtmlBlockDiv _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenDiv) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockDiv) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseDiv) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseDiv) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockDiv unless _tmp return _tmp end # HtmlBlockOpenDl = "<" Spnl ("dl" | "DL") Spnl HtmlAttribute* ">" def _HtmlBlockOpenDl _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("dl") break if _tmp self.pos = _save1 _tmp = match_string("DL") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenDl unless _tmp return _tmp end # HtmlBlockCloseDl = "<" Spnl "/" ("dl" | "DL") Spnl ">" def _HtmlBlockCloseDl _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("dl") break if _tmp self.pos = _save1 _tmp = match_string("DL") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseDl unless _tmp return _tmp end # HtmlBlockDl = HtmlBlockOpenDl (HtmlBlockDl | !HtmlBlockCloseDl .)* HtmlBlockCloseDl def _HtmlBlockDl _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenDl) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockDl) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseDl) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseDl) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockDl unless _tmp return _tmp end # HtmlBlockOpenFieldset = "<" Spnl ("fieldset" | "FIELDSET") Spnl HtmlAttribute* ">" def _HtmlBlockOpenFieldset _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("fieldset") break if _tmp self.pos = _save1 _tmp = match_string("FIELDSET") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenFieldset unless _tmp return _tmp end # HtmlBlockCloseFieldset = "<" Spnl "/" ("fieldset" | "FIELDSET") Spnl ">" def _HtmlBlockCloseFieldset _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("fieldset") break if _tmp self.pos = _save1 _tmp = match_string("FIELDSET") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseFieldset unless _tmp return _tmp end # HtmlBlockFieldset = HtmlBlockOpenFieldset (HtmlBlockFieldset | !HtmlBlockCloseFieldset .)* HtmlBlockCloseFieldset def _HtmlBlockFieldset _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenFieldset) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockFieldset) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseFieldset) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseFieldset) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockFieldset unless _tmp return _tmp end # HtmlBlockOpenForm = "<" Spnl ("form" | "FORM") Spnl HtmlAttribute* ">" def _HtmlBlockOpenForm _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("form") break if _tmp self.pos = _save1 _tmp = match_string("FORM") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenForm unless _tmp return _tmp end # HtmlBlockCloseForm = "<" Spnl "/" ("form" | "FORM") Spnl ">" def _HtmlBlockCloseForm _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("form") break if _tmp self.pos = _save1 _tmp = match_string("FORM") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseForm unless _tmp return _tmp end # HtmlBlockForm = HtmlBlockOpenForm (HtmlBlockForm | !HtmlBlockCloseForm .)* HtmlBlockCloseForm def _HtmlBlockForm _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenForm) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockForm) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseForm) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseForm) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockForm unless _tmp return _tmp end # HtmlBlockOpenH1 = "<" Spnl ("h1" | "H1") Spnl HtmlAttribute* ">" def _HtmlBlockOpenH1 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h1") break if _tmp self.pos = _save1 _tmp = match_string("H1") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenH1 unless _tmp return _tmp end # HtmlBlockCloseH1 = "<" Spnl "/" ("h1" | "H1") Spnl ">" def _HtmlBlockCloseH1 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h1") break if _tmp self.pos = _save1 _tmp = match_string("H1") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseH1 unless _tmp return _tmp end # HtmlBlockH1 = HtmlBlockOpenH1 (HtmlBlockH1 | !HtmlBlockCloseH1 .)* HtmlBlockCloseH1 def _HtmlBlockH1 _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenH1) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockH1) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseH1) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseH1) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockH1 unless _tmp return _tmp end # HtmlBlockOpenH2 = "<" Spnl ("h2" | "H2") Spnl HtmlAttribute* ">" def _HtmlBlockOpenH2 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h2") break if _tmp self.pos = _save1 _tmp = match_string("H2") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenH2 unless _tmp return _tmp end # HtmlBlockCloseH2 = "<" Spnl "/" ("h2" | "H2") Spnl ">" def _HtmlBlockCloseH2 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h2") break if _tmp self.pos = _save1 _tmp = match_string("H2") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseH2 unless _tmp return _tmp end # HtmlBlockH2 = HtmlBlockOpenH2 (HtmlBlockH2 | !HtmlBlockCloseH2 .)* HtmlBlockCloseH2 def _HtmlBlockH2 _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenH2) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockH2) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseH2) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseH2) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockH2 unless _tmp return _tmp end # HtmlBlockOpenH3 = "<" Spnl ("h3" | "H3") Spnl HtmlAttribute* ">" def _HtmlBlockOpenH3 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h3") break if _tmp self.pos = _save1 _tmp = match_string("H3") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenH3 unless _tmp return _tmp end # HtmlBlockCloseH3 = "<" Spnl "/" ("h3" | "H3") Spnl ">" def _HtmlBlockCloseH3 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h3") break if _tmp self.pos = _save1 _tmp = match_string("H3") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseH3 unless _tmp return _tmp end # HtmlBlockH3 = HtmlBlockOpenH3 (HtmlBlockH3 | !HtmlBlockCloseH3 .)* HtmlBlockCloseH3 def _HtmlBlockH3 _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenH3) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockH3) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseH3) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseH3) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockH3 unless _tmp return _tmp end # HtmlBlockOpenH4 = "<" Spnl ("h4" | "H4") Spnl HtmlAttribute* ">" def _HtmlBlockOpenH4 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h4") break if _tmp self.pos = _save1 _tmp = match_string("H4") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenH4 unless _tmp return _tmp end # HtmlBlockCloseH4 = "<" Spnl "/" ("h4" | "H4") Spnl ">" def _HtmlBlockCloseH4 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h4") break if _tmp self.pos = _save1 _tmp = match_string("H4") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseH4 unless _tmp return _tmp end # HtmlBlockH4 = HtmlBlockOpenH4 (HtmlBlockH4 | !HtmlBlockCloseH4 .)* HtmlBlockCloseH4 def _HtmlBlockH4 _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenH4) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockH4) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseH4) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseH4) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockH4 unless _tmp return _tmp end # HtmlBlockOpenH5 = "<" Spnl ("h5" | "H5") Spnl HtmlAttribute* ">" def _HtmlBlockOpenH5 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h5") break if _tmp self.pos = _save1 _tmp = match_string("H5") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenH5 unless _tmp return _tmp end # HtmlBlockCloseH5 = "<" Spnl "/" ("h5" | "H5") Spnl ">" def _HtmlBlockCloseH5 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h5") break if _tmp self.pos = _save1 _tmp = match_string("H5") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseH5 unless _tmp return _tmp end # HtmlBlockH5 = HtmlBlockOpenH5 (HtmlBlockH5 | !HtmlBlockCloseH5 .)* HtmlBlockCloseH5 def _HtmlBlockH5 _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenH5) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockH5) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseH5) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseH5) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockH5 unless _tmp return _tmp end # HtmlBlockOpenH6 = "<" Spnl ("h6" | "H6") Spnl HtmlAttribute* ">" def _HtmlBlockOpenH6 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h6") break if _tmp self.pos = _save1 _tmp = match_string("H6") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenH6 unless _tmp return _tmp end # HtmlBlockCloseH6 = "<" Spnl "/" ("h6" | "H6") Spnl ">" def _HtmlBlockCloseH6 _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("h6") break if _tmp self.pos = _save1 _tmp = match_string("H6") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseH6 unless _tmp return _tmp end # HtmlBlockH6 = HtmlBlockOpenH6 (HtmlBlockH6 | !HtmlBlockCloseH6 .)* HtmlBlockCloseH6 def _HtmlBlockH6 _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenH6) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockH6) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseH6) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseH6) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockH6 unless _tmp return _tmp end # HtmlBlockOpenMenu = "<" Spnl ("menu" | "MENU") Spnl HtmlAttribute* ">" def _HtmlBlockOpenMenu _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("menu") break if _tmp self.pos = _save1 _tmp = match_string("MENU") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenMenu unless _tmp return _tmp end # HtmlBlockCloseMenu = "<" Spnl "/" ("menu" | "MENU") Spnl ">" def _HtmlBlockCloseMenu _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("menu") break if _tmp self.pos = _save1 _tmp = match_string("MENU") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseMenu unless _tmp return _tmp end # HtmlBlockMenu = HtmlBlockOpenMenu (HtmlBlockMenu | !HtmlBlockCloseMenu .)* HtmlBlockCloseMenu def _HtmlBlockMenu _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenMenu) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockMenu) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseMenu) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseMenu) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockMenu unless _tmp return _tmp end # HtmlBlockOpenNoframes = "<" Spnl ("noframes" | "NOFRAMES") Spnl HtmlAttribute* ">" def _HtmlBlockOpenNoframes _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("noframes") break if _tmp self.pos = _save1 _tmp = match_string("NOFRAMES") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenNoframes unless _tmp return _tmp end # HtmlBlockCloseNoframes = "<" Spnl "/" ("noframes" | "NOFRAMES") Spnl ">" def _HtmlBlockCloseNoframes _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("noframes") break if _tmp self.pos = _save1 _tmp = match_string("NOFRAMES") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseNoframes unless _tmp return _tmp end # HtmlBlockNoframes = HtmlBlockOpenNoframes (HtmlBlockNoframes | !HtmlBlockCloseNoframes .)* HtmlBlockCloseNoframes def _HtmlBlockNoframes _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenNoframes) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockNoframes) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseNoframes) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseNoframes) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockNoframes unless _tmp return _tmp end # HtmlBlockOpenNoscript = "<" Spnl ("noscript" | "NOSCRIPT") Spnl HtmlAttribute* ">" def _HtmlBlockOpenNoscript _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("noscript") break if _tmp self.pos = _save1 _tmp = match_string("NOSCRIPT") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenNoscript unless _tmp return _tmp end # HtmlBlockCloseNoscript = "<" Spnl "/" ("noscript" | "NOSCRIPT") Spnl ">" def _HtmlBlockCloseNoscript _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("noscript") break if _tmp self.pos = _save1 _tmp = match_string("NOSCRIPT") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseNoscript unless _tmp return _tmp end # HtmlBlockNoscript = HtmlBlockOpenNoscript (HtmlBlockNoscript | !HtmlBlockCloseNoscript .)* HtmlBlockCloseNoscript def _HtmlBlockNoscript _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenNoscript) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockNoscript) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseNoscript) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseNoscript) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockNoscript unless _tmp return _tmp end # HtmlBlockOpenOl = "<" Spnl ("ol" | "OL") Spnl HtmlAttribute* ">" def _HtmlBlockOpenOl _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("ol") break if _tmp self.pos = _save1 _tmp = match_string("OL") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenOl unless _tmp return _tmp end # HtmlBlockCloseOl = "<" Spnl "/" ("ol" | "OL") Spnl ">" def _HtmlBlockCloseOl _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("ol") break if _tmp self.pos = _save1 _tmp = match_string("OL") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseOl unless _tmp return _tmp end # HtmlBlockOl = HtmlBlockOpenOl (HtmlBlockOl | !HtmlBlockCloseOl .)* HtmlBlockCloseOl def _HtmlBlockOl _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenOl) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockOl) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseOl) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseOl) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOl unless _tmp return _tmp end # HtmlBlockOpenP = "<" Spnl ("p" | "P") Spnl HtmlAttribute* ">" def _HtmlBlockOpenP _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("p") break if _tmp self.pos = _save1 _tmp = match_string("P") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenP unless _tmp return _tmp end # HtmlBlockCloseP = "<" Spnl "/" ("p" | "P") Spnl ">" def _HtmlBlockCloseP _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("p") break if _tmp self.pos = _save1 _tmp = match_string("P") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseP unless _tmp return _tmp end # HtmlBlockP = HtmlBlockOpenP (HtmlBlockP | !HtmlBlockCloseP .)* HtmlBlockCloseP def _HtmlBlockP _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenP) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockP) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseP) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseP) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockP unless _tmp return _tmp end # HtmlBlockOpenPre = "<" Spnl ("pre" | "PRE") Spnl HtmlAttribute* ">" def _HtmlBlockOpenPre _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("pre") break if _tmp self.pos = _save1 _tmp = match_string("PRE") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenPre unless _tmp return _tmp end # HtmlBlockClosePre = "<" Spnl "/" ("pre" | "PRE") Spnl ">" def _HtmlBlockClosePre _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("pre") break if _tmp self.pos = _save1 _tmp = match_string("PRE") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockClosePre unless _tmp return _tmp end # HtmlBlockPre = HtmlBlockOpenPre (HtmlBlockPre | !HtmlBlockClosePre .)* HtmlBlockClosePre def _HtmlBlockPre _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenPre) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockPre) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockClosePre) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockClosePre) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockPre unless _tmp return _tmp end # HtmlBlockOpenTable = "<" Spnl ("table" | "TABLE") Spnl HtmlAttribute* ">" def _HtmlBlockOpenTable _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("table") break if _tmp self.pos = _save1 _tmp = match_string("TABLE") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenTable unless _tmp return _tmp end # HtmlBlockCloseTable = "<" Spnl "/" ("table" | "TABLE") Spnl ">" def _HtmlBlockCloseTable _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("table") break if _tmp self.pos = _save1 _tmp = match_string("TABLE") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseTable unless _tmp return _tmp end # HtmlBlockTable = HtmlBlockOpenTable (HtmlBlockTable | !HtmlBlockCloseTable .)* HtmlBlockCloseTable def _HtmlBlockTable _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenTable) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockTable) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseTable) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseTable) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockTable unless _tmp return _tmp end # HtmlBlockOpenUl = "<" Spnl ("ul" | "UL") Spnl HtmlAttribute* ">" def _HtmlBlockOpenUl _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("ul") break if _tmp self.pos = _save1 _tmp = match_string("UL") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenUl unless _tmp return _tmp end # HtmlBlockCloseUl = "<" Spnl "/" ("ul" | "UL") Spnl ">" def _HtmlBlockCloseUl _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("ul") break if _tmp self.pos = _save1 _tmp = match_string("UL") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseUl unless _tmp return _tmp end # HtmlBlockUl = HtmlBlockOpenUl (HtmlBlockUl | !HtmlBlockCloseUl .)* HtmlBlockCloseUl def _HtmlBlockUl _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenUl) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockUl) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseUl) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseUl) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockUl unless _tmp return _tmp end # HtmlBlockOpenDd = "<" Spnl ("dd" | "DD") Spnl HtmlAttribute* ">" def _HtmlBlockOpenDd _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("dd") break if _tmp self.pos = _save1 _tmp = match_string("DD") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenDd unless _tmp return _tmp end # HtmlBlockCloseDd = "<" Spnl "/" ("dd" | "DD") Spnl ">" def _HtmlBlockCloseDd _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("dd") break if _tmp self.pos = _save1 _tmp = match_string("DD") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseDd unless _tmp return _tmp end # HtmlBlockDd = HtmlBlockOpenDd (HtmlBlockDd | !HtmlBlockCloseDd .)* HtmlBlockCloseDd def _HtmlBlockDd _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenDd) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockDd) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseDd) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseDd) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockDd unless _tmp return _tmp end # HtmlBlockOpenDt = "<" Spnl ("dt" | "DT") Spnl HtmlAttribute* ">" def _HtmlBlockOpenDt _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("dt") break if _tmp self.pos = _save1 _tmp = match_string("DT") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenDt unless _tmp return _tmp end # HtmlBlockCloseDt = "<" Spnl "/" ("dt" | "DT") Spnl ">" def _HtmlBlockCloseDt _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("dt") break if _tmp self.pos = _save1 _tmp = match_string("DT") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseDt unless _tmp return _tmp end # HtmlBlockDt = HtmlBlockOpenDt (HtmlBlockDt | !HtmlBlockCloseDt .)* HtmlBlockCloseDt def _HtmlBlockDt _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenDt) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockDt) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseDt) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseDt) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockDt unless _tmp return _tmp end # HtmlBlockOpenFrameset = "<" Spnl ("frameset" | "FRAMESET") Spnl HtmlAttribute* ">" def _HtmlBlockOpenFrameset _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("frameset") break if _tmp self.pos = _save1 _tmp = match_string("FRAMESET") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenFrameset unless _tmp return _tmp end # HtmlBlockCloseFrameset = "<" Spnl "/" ("frameset" | "FRAMESET") Spnl ">" def _HtmlBlockCloseFrameset _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("frameset") break if _tmp self.pos = _save1 _tmp = match_string("FRAMESET") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseFrameset unless _tmp return _tmp end # HtmlBlockFrameset = HtmlBlockOpenFrameset (HtmlBlockFrameset | !HtmlBlockCloseFrameset .)* HtmlBlockCloseFrameset def _HtmlBlockFrameset _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenFrameset) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockFrameset) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseFrameset) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseFrameset) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockFrameset unless _tmp return _tmp end # HtmlBlockOpenLi = "<" Spnl ("li" | "LI") Spnl HtmlAttribute* ">" def _HtmlBlockOpenLi _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("li") break if _tmp self.pos = _save1 _tmp = match_string("LI") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenLi unless _tmp return _tmp end # HtmlBlockCloseLi = "<" Spnl "/" ("li" | "LI") Spnl ">" def _HtmlBlockCloseLi _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("li") break if _tmp self.pos = _save1 _tmp = match_string("LI") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseLi unless _tmp return _tmp end # HtmlBlockLi = HtmlBlockOpenLi (HtmlBlockLi | !HtmlBlockCloseLi .)* HtmlBlockCloseLi def _HtmlBlockLi _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenLi) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockLi) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseLi) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseLi) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockLi unless _tmp return _tmp end # HtmlBlockOpenTbody = "<" Spnl ("tbody" | "TBODY") Spnl HtmlAttribute* ">" def _HtmlBlockOpenTbody _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("tbody") break if _tmp self.pos = _save1 _tmp = match_string("TBODY") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenTbody unless _tmp return _tmp end # HtmlBlockCloseTbody = "<" Spnl "/" ("tbody" | "TBODY") Spnl ">" def _HtmlBlockCloseTbody _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("tbody") break if _tmp self.pos = _save1 _tmp = match_string("TBODY") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseTbody unless _tmp return _tmp end # HtmlBlockTbody = HtmlBlockOpenTbody (HtmlBlockTbody | !HtmlBlockCloseTbody .)* HtmlBlockCloseTbody def _HtmlBlockTbody _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenTbody) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockTbody) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseTbody) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseTbody) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockTbody unless _tmp return _tmp end # HtmlBlockOpenTd = "<" Spnl ("td" | "TD") Spnl HtmlAttribute* ">" def _HtmlBlockOpenTd _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("td") break if _tmp self.pos = _save1 _tmp = match_string("TD") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenTd unless _tmp return _tmp end # HtmlBlockCloseTd = "<" Spnl "/" ("td" | "TD") Spnl ">" def _HtmlBlockCloseTd _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("td") break if _tmp self.pos = _save1 _tmp = match_string("TD") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseTd unless _tmp return _tmp end # HtmlBlockTd = HtmlBlockOpenTd (HtmlBlockTd | !HtmlBlockCloseTd .)* HtmlBlockCloseTd def _HtmlBlockTd _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenTd) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockTd) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseTd) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseTd) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockTd unless _tmp return _tmp end # HtmlBlockOpenTfoot = "<" Spnl ("tfoot" | "TFOOT") Spnl HtmlAttribute* ">" def _HtmlBlockOpenTfoot _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("tfoot") break if _tmp self.pos = _save1 _tmp = match_string("TFOOT") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenTfoot unless _tmp return _tmp end # HtmlBlockCloseTfoot = "<" Spnl "/" ("tfoot" | "TFOOT") Spnl ">" def _HtmlBlockCloseTfoot _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("tfoot") break if _tmp self.pos = _save1 _tmp = match_string("TFOOT") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseTfoot unless _tmp return _tmp end # HtmlBlockTfoot = HtmlBlockOpenTfoot (HtmlBlockTfoot | !HtmlBlockCloseTfoot .)* HtmlBlockCloseTfoot def _HtmlBlockTfoot _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenTfoot) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockTfoot) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseTfoot) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseTfoot) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockTfoot unless _tmp return _tmp end # HtmlBlockOpenTh = "<" Spnl ("th" | "TH") Spnl HtmlAttribute* ">" def _HtmlBlockOpenTh _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("th") break if _tmp self.pos = _save1 _tmp = match_string("TH") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenTh unless _tmp return _tmp end # HtmlBlockCloseTh = "<" Spnl "/" ("th" | "TH") Spnl ">" def _HtmlBlockCloseTh _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("th") break if _tmp self.pos = _save1 _tmp = match_string("TH") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseTh unless _tmp return _tmp end # HtmlBlockTh = HtmlBlockOpenTh (HtmlBlockTh | !HtmlBlockCloseTh .)* HtmlBlockCloseTh def _HtmlBlockTh _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenTh) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockTh) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseTh) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseTh) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockTh unless _tmp return _tmp end # HtmlBlockOpenThead = "<" Spnl ("thead" | "THEAD") Spnl HtmlAttribute* ">" def _HtmlBlockOpenThead _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("thead") break if _tmp self.pos = _save1 _tmp = match_string("THEAD") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenThead unless _tmp return _tmp end # HtmlBlockCloseThead = "<" Spnl "/" ("thead" | "THEAD") Spnl ">" def _HtmlBlockCloseThead _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("thead") break if _tmp self.pos = _save1 _tmp = match_string("THEAD") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseThead unless _tmp return _tmp end # HtmlBlockThead = HtmlBlockOpenThead (HtmlBlockThead | !HtmlBlockCloseThead .)* HtmlBlockCloseThead def _HtmlBlockThead _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenThead) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockThead) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseThead) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseThead) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockThead unless _tmp return _tmp end # HtmlBlockOpenTr = "<" Spnl ("tr" | "TR") Spnl HtmlAttribute* ">" def _HtmlBlockOpenTr _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("tr") break if _tmp self.pos = _save1 _tmp = match_string("TR") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenTr unless _tmp return _tmp end # HtmlBlockCloseTr = "<" Spnl "/" ("tr" | "TR") Spnl ">" def _HtmlBlockCloseTr _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("tr") break if _tmp self.pos = _save1 _tmp = match_string("TR") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseTr unless _tmp return _tmp end # HtmlBlockTr = HtmlBlockOpenTr (HtmlBlockTr | !HtmlBlockCloseTr .)* HtmlBlockCloseTr def _HtmlBlockTr _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenTr) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # choice _tmp = apply(:_HtmlBlockTr) break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_HtmlBlockCloseTr) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseTr) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockTr unless _tmp return _tmp end # HtmlBlockOpenScript = "<" Spnl ("script" | "SCRIPT") Spnl HtmlAttribute* ">" def _HtmlBlockOpenScript _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("script") break if _tmp self.pos = _save1 _tmp = match_string("SCRIPT") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenScript unless _tmp return _tmp end # HtmlBlockCloseScript = "<" Spnl "/" ("script" | "SCRIPT") Spnl ">" def _HtmlBlockCloseScript _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("script") break if _tmp self.pos = _save1 _tmp = match_string("SCRIPT") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseScript unless _tmp return _tmp end # HtmlBlockScript = HtmlBlockOpenScript (!HtmlBlockCloseScript .)* HtmlBlockCloseScript def _HtmlBlockScript _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenScript) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # sequence _save3 = self.pos _tmp = apply(:_HtmlBlockCloseScript) _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseScript) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockScript unless _tmp return _tmp end # HtmlBlockOpenHead = "<" Spnl ("head" | "HEAD") Spnl HtmlAttribute* ">" def _HtmlBlockOpenHead _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("head") break if _tmp self.pos = _save1 _tmp = match_string("HEAD") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockOpenHead unless _tmp return _tmp end # HtmlBlockCloseHead = "<" Spnl "/" ("head" | "HEAD") Spnl ">" def _HtmlBlockCloseHead _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("head") break if _tmp self.pos = _save1 _tmp = match_string("HEAD") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockCloseHead unless _tmp return _tmp end # HtmlBlockHead = HtmlBlockOpenHead (!HtmlBlockCloseHead .)* HtmlBlockCloseHead def _HtmlBlockHead _save = self.pos while true # sequence _tmp = apply(:_HtmlBlockOpenHead) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # sequence _save3 = self.pos _tmp = apply(:_HtmlBlockCloseHead) _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockCloseHead) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockHead unless _tmp return _tmp end # HtmlBlockInTags = (HtmlAnchor | HtmlBlockAddress | HtmlBlockBlockquote | HtmlBlockCenter | HtmlBlockDir | HtmlBlockDiv | HtmlBlockDl | HtmlBlockFieldset | HtmlBlockForm | HtmlBlockH1 | HtmlBlockH2 | HtmlBlockH3 | HtmlBlockH4 | HtmlBlockH5 | HtmlBlockH6 | HtmlBlockMenu | HtmlBlockNoframes | HtmlBlockNoscript | HtmlBlockOl | HtmlBlockP | HtmlBlockPre | HtmlBlockTable | HtmlBlockUl | HtmlBlockDd | HtmlBlockDt | HtmlBlockFrameset | HtmlBlockLi | HtmlBlockTbody | HtmlBlockTd | HtmlBlockTfoot | HtmlBlockTh | HtmlBlockThead | HtmlBlockTr | HtmlBlockScript | HtmlBlockHead) def _HtmlBlockInTags _save = self.pos while true # choice _tmp = apply(:_HtmlAnchor) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockAddress) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockBlockquote) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockCenter) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockDir) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockDiv) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockDl) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockFieldset) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockForm) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockH1) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockH2) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockH3) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockH4) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockH5) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockH6) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockMenu) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockNoframes) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockNoscript) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockOl) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockP) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockPre) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockTable) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockUl) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockDd) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockDt) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockFrameset) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockLi) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockTbody) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockTd) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockTfoot) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockTh) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockThead) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockTr) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockScript) break if _tmp self.pos = _save _tmp = apply(:_HtmlBlockHead) break if _tmp self.pos = _save break end # end choice set_failed_rule :_HtmlBlockInTags unless _tmp return _tmp end # HtmlBlock = < (HtmlBlockInTags | HtmlComment | HtmlBlockSelfClosing | HtmlUnclosed) > @BlankLine+ { if html? then RDoc::Markup::Raw.new text end } def _HtmlBlock _save = self.pos while true # sequence _text_start = self.pos _save1 = self.pos while true # choice _tmp = apply(:_HtmlBlockInTags) break if _tmp self.pos = _save1 _tmp = apply(:_HtmlComment) break if _tmp self.pos = _save1 _tmp = apply(:_HtmlBlockSelfClosing) break if _tmp self.pos = _save1 _tmp = apply(:_HtmlUnclosed) break if _tmp self.pos = _save1 break end # end choice if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _save2 = self.pos _tmp = _BlankLine() if _tmp while true _tmp = _BlankLine() break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save break end @result = begin; if html? then RDoc::Markup::Raw.new text end ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlock unless _tmp return _tmp end # HtmlUnclosed = "<" Spnl HtmlUnclosedType Spnl HtmlAttribute* Spnl ">" def _HtmlUnclosed _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = apply(:_HtmlUnclosedType) unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlUnclosed unless _tmp return _tmp end # HtmlUnclosedType = ("HR" | "hr") def _HtmlUnclosedType _save = self.pos while true # choice _tmp = match_string("HR") break if _tmp self.pos = _save _tmp = match_string("hr") break if _tmp self.pos = _save break end # end choice set_failed_rule :_HtmlUnclosedType unless _tmp return _tmp end # HtmlBlockSelfClosing = "<" Spnl HtmlBlockType Spnl HtmlAttribute* "/" Spnl ">" def _HtmlBlockSelfClosing _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = apply(:_HtmlBlockType) unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlBlockSelfClosing unless _tmp return _tmp end # HtmlBlockType = ("ADDRESS" | "BLOCKQUOTE" | "CENTER" | "DD" | "DIR" | "DIV" | "DL" | "DT" | "FIELDSET" | "FORM" | "FRAMESET" | "H1" | "H2" | "H3" | "H4" | "H5" | "H6" | "HR" | "ISINDEX" | "LI" | "MENU" | "NOFRAMES" | "NOSCRIPT" | "OL" | "P" | "PRE" | "SCRIPT" | "TABLE" | "TBODY" | "TD" | "TFOOT" | "TH" | "THEAD" | "TR" | "UL" | "address" | "blockquote" | "center" | "dd" | "dir" | "div" | "dl" | "dt" | "fieldset" | "form" | "frameset" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "hr" | "isindex" | "li" | "menu" | "noframes" | "noscript" | "ol" | "p" | "pre" | "script" | "table" | "tbody" | "td" | "tfoot" | "th" | "thead" | "tr" | "ul") def _HtmlBlockType _save = self.pos while true # choice _tmp = match_string("ADDRESS") break if _tmp self.pos = _save _tmp = match_string("BLOCKQUOTE") break if _tmp self.pos = _save _tmp = match_string("CENTER") break if _tmp self.pos = _save _tmp = match_string("DD") break if _tmp self.pos = _save _tmp = match_string("DIR") break if _tmp self.pos = _save _tmp = match_string("DIV") break if _tmp self.pos = _save _tmp = match_string("DL") break if _tmp self.pos = _save _tmp = match_string("DT") break if _tmp self.pos = _save _tmp = match_string("FIELDSET") break if _tmp self.pos = _save _tmp = match_string("FORM") break if _tmp self.pos = _save _tmp = match_string("FRAMESET") break if _tmp self.pos = _save _tmp = match_string("H1") break if _tmp self.pos = _save _tmp = match_string("H2") break if _tmp self.pos = _save _tmp = match_string("H3") break if _tmp self.pos = _save _tmp = match_string("H4") break if _tmp self.pos = _save _tmp = match_string("H5") break if _tmp self.pos = _save _tmp = match_string("H6") break if _tmp self.pos = _save _tmp = match_string("HR") break if _tmp self.pos = _save _tmp = match_string("ISINDEX") break if _tmp self.pos = _save _tmp = match_string("LI") break if _tmp self.pos = _save _tmp = match_string("MENU") break if _tmp self.pos = _save _tmp = match_string("NOFRAMES") break if _tmp self.pos = _save _tmp = match_string("NOSCRIPT") break if _tmp self.pos = _save _tmp = match_string("OL") break if _tmp self.pos = _save _tmp = match_string("P") break if _tmp self.pos = _save _tmp = match_string("PRE") break if _tmp self.pos = _save _tmp = match_string("SCRIPT") break if _tmp self.pos = _save _tmp = match_string("TABLE") break if _tmp self.pos = _save _tmp = match_string("TBODY") break if _tmp self.pos = _save _tmp = match_string("TD") break if _tmp self.pos = _save _tmp = match_string("TFOOT") break if _tmp self.pos = _save _tmp = match_string("TH") break if _tmp self.pos = _save _tmp = match_string("THEAD") break if _tmp self.pos = _save _tmp = match_string("TR") break if _tmp self.pos = _save _tmp = match_string("UL") break if _tmp self.pos = _save _tmp = match_string("address") break if _tmp self.pos = _save _tmp = match_string("blockquote") break if _tmp self.pos = _save _tmp = match_string("center") break if _tmp self.pos = _save _tmp = match_string("dd") break if _tmp self.pos = _save _tmp = match_string("dir") break if _tmp self.pos = _save _tmp = match_string("div") break if _tmp self.pos = _save _tmp = match_string("dl") break if _tmp self.pos = _save _tmp = match_string("dt") break if _tmp self.pos = _save _tmp = match_string("fieldset") break if _tmp self.pos = _save _tmp = match_string("form") break if _tmp self.pos = _save _tmp = match_string("frameset") break if _tmp self.pos = _save _tmp = match_string("h1") break if _tmp self.pos = _save _tmp = match_string("h2") break if _tmp self.pos = _save _tmp = match_string("h3") break if _tmp self.pos = _save _tmp = match_string("h4") break if _tmp self.pos = _save _tmp = match_string("h5") break if _tmp self.pos = _save _tmp = match_string("h6") break if _tmp self.pos = _save _tmp = match_string("hr") break if _tmp self.pos = _save _tmp = match_string("isindex") break if _tmp self.pos = _save _tmp = match_string("li") break if _tmp self.pos = _save _tmp = match_string("menu") break if _tmp self.pos = _save _tmp = match_string("noframes") break if _tmp self.pos = _save _tmp = match_string("noscript") break if _tmp self.pos = _save _tmp = match_string("ol") break if _tmp self.pos = _save _tmp = match_string("p") break if _tmp self.pos = _save _tmp = match_string("pre") break if _tmp self.pos = _save _tmp = match_string("script") break if _tmp self.pos = _save _tmp = match_string("table") break if _tmp self.pos = _save _tmp = match_string("tbody") break if _tmp self.pos = _save _tmp = match_string("td") break if _tmp self.pos = _save _tmp = match_string("tfoot") break if _tmp self.pos = _save _tmp = match_string("th") break if _tmp self.pos = _save _tmp = match_string("thead") break if _tmp self.pos = _save _tmp = match_string("tr") break if _tmp self.pos = _save _tmp = match_string("ul") break if _tmp self.pos = _save break end # end choice set_failed_rule :_HtmlBlockType unless _tmp return _tmp end # StyleOpen = "<" Spnl ("style" | "STYLE") Spnl HtmlAttribute* ">" def _StyleOpen _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("style") break if _tmp self.pos = _save1 _tmp = match_string("STYLE") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_StyleOpen unless _tmp return _tmp end # StyleClose = "<" Spnl "/" ("style" | "STYLE") Spnl ">" def _StyleClose _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("/") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = match_string("style") break if _tmp self.pos = _save1 _tmp = match_string("STYLE") break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_StyleClose unless _tmp return _tmp end # InStyleTags = StyleOpen (!StyleClose .)* StyleClose def _InStyleTags _save = self.pos while true # sequence _tmp = apply(:_StyleOpen) unless _tmp self.pos = _save break end while true _save2 = self.pos while true # sequence _save3 = self.pos _tmp = apply(:_StyleClose) _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = apply(:_StyleClose) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_InStyleTags unless _tmp return _tmp end # StyleBlock = < InStyleTags > @BlankLine* { if css? then RDoc::Markup::Raw.new text end } def _StyleBlock _save = self.pos while true # sequence _text_start = self.pos _tmp = apply(:_InStyleTags) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end while true _tmp = _BlankLine() break unless _tmp end _tmp = true unless _tmp self.pos = _save break end @result = begin; if css? then RDoc::Markup::Raw.new text end ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_StyleBlock unless _tmp return _tmp end # Inlines = (!@Endline Inline:i { i } | @Endline:c !(&{ github? } Ticks3 /[^`\n]*$/) &Inline { c })+:chunks @Endline? { chunks } def _Inlines _save = self.pos while true # sequence _save1 = self.pos _ary = [] _save2 = self.pos while true # choice _save3 = self.pos while true # sequence _save4 = self.pos _tmp = _Endline() _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = apply(:_Inline) i = @result unless _tmp self.pos = _save3 break end @result = begin; i ; end _tmp = true unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 _save5 = self.pos while true # sequence _tmp = _Endline() c = @result unless _tmp self.pos = _save5 break end _save6 = self.pos _save7 = self.pos while true # sequence _save8 = self.pos _tmp = begin; github? ; end self.pos = _save8 unless _tmp self.pos = _save7 break end _tmp = apply(:_Ticks3) unless _tmp self.pos = _save7 break end _tmp = scan(/\G(?-mix:[^`\n]*$)/) unless _tmp self.pos = _save7 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save5 break end _save9 = self.pos _tmp = apply(:_Inline) self.pos = _save9 unless _tmp self.pos = _save5 break end @result = begin; c ; end _tmp = true unless _tmp self.pos = _save5 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice if _tmp _ary << @result while true _save10 = self.pos while true # choice _save11 = self.pos while true # sequence _save12 = self.pos _tmp = _Endline() _tmp = _tmp ? nil : true self.pos = _save12 unless _tmp self.pos = _save11 break end _tmp = apply(:_Inline) i = @result unless _tmp self.pos = _save11 break end @result = begin; i ; end _tmp = true unless _tmp self.pos = _save11 end break end # end sequence break if _tmp self.pos = _save10 _save13 = self.pos while true # sequence _tmp = _Endline() c = @result unless _tmp self.pos = _save13 break end _save14 = self.pos _save15 = self.pos while true # sequence _save16 = self.pos _tmp = begin; github? ; end self.pos = _save16 unless _tmp self.pos = _save15 break end _tmp = apply(:_Ticks3) unless _tmp self.pos = _save15 break end _tmp = scan(/\G(?-mix:[^`\n]*$)/) unless _tmp self.pos = _save15 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save14 unless _tmp self.pos = _save13 break end _save17 = self.pos _tmp = apply(:_Inline) self.pos = _save17 unless _tmp self.pos = _save13 break end @result = begin; c ; end _tmp = true unless _tmp self.pos = _save13 end break end # end sequence break if _tmp self.pos = _save10 break end # end choice _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save1 end chunks = @result unless _tmp self.pos = _save break end _save18 = self.pos _tmp = _Endline() unless _tmp _tmp = true self.pos = _save18 end unless _tmp self.pos = _save break end @result = begin; chunks ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Inlines unless _tmp return _tmp end # Inline = (Str | @Endline | UlOrStarLine | @Space | Strong | Emph | Strike | Image | Link | NoteReference | InlineNote | Code | RawHtml | Entity | EscapedChar | Symbol) def _Inline _save = self.pos while true # choice _tmp = apply(:_Str) break if _tmp self.pos = _save _tmp = _Endline() break if _tmp self.pos = _save _tmp = apply(:_UlOrStarLine) break if _tmp self.pos = _save _tmp = _Space() break if _tmp self.pos = _save _tmp = apply(:_Strong) break if _tmp self.pos = _save _tmp = apply(:_Emph) break if _tmp self.pos = _save _tmp = apply(:_Strike) break if _tmp self.pos = _save _tmp = apply(:_Image) break if _tmp self.pos = _save _tmp = apply(:_Link) break if _tmp self.pos = _save _tmp = apply(:_NoteReference) break if _tmp self.pos = _save _tmp = apply(:_InlineNote) break if _tmp self.pos = _save _tmp = apply(:_Code) break if _tmp self.pos = _save _tmp = apply(:_RawHtml) break if _tmp self.pos = _save _tmp = apply(:_Entity) break if _tmp self.pos = _save _tmp = apply(:_EscapedChar) break if _tmp self.pos = _save _tmp = apply(:_Symbol) break if _tmp self.pos = _save break end # end choice set_failed_rule :_Inline unless _tmp return _tmp end # Space = @Spacechar+ { " " } def _Space _save = self.pos while true # sequence _save1 = self.pos _tmp = _Spacechar() if _tmp while true _tmp = _Spacechar() break unless _tmp end _tmp = true else self.pos = _save1 end unless _tmp self.pos = _save break end @result = begin; " " ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Space unless _tmp return _tmp end # Str = @StartList:a < @NormalChar+ > { a = text } (StrChunk:c { a << c })* { a } def _Str _save = self.pos while true # sequence _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _text_start = self.pos _save1 = self.pos _tmp = _NormalChar() if _tmp while true _tmp = _NormalChar() break unless _tmp end _tmp = true else self.pos = _save1 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; a = text ; end _tmp = true unless _tmp self.pos = _save break end while true _save3 = self.pos while true # sequence _tmp = apply(:_StrChunk) c = @result unless _tmp self.pos = _save3 break end @result = begin; a << c ; end _tmp = true unless _tmp self.pos = _save3 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end @result = begin; a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Str unless _tmp return _tmp end # StrChunk = < (@NormalChar | /_+/ &Alphanumeric)+ > { text } def _StrChunk _save = self.pos while true # sequence _text_start = self.pos _save1 = self.pos _save2 = self.pos while true # choice _tmp = _NormalChar() break if _tmp self.pos = _save2 _save3 = self.pos while true # sequence _tmp = scan(/\G(?-mix:_+)/) unless _tmp self.pos = _save3 break end _save4 = self.pos _tmp = apply(:_Alphanumeric) self.pos = _save4 unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save2 break end # end choice if _tmp while true _save5 = self.pos while true # choice _tmp = _NormalChar() break if _tmp self.pos = _save5 _save6 = self.pos while true # sequence _tmp = scan(/\G(?-mix:_+)/) unless _tmp self.pos = _save6 break end _save7 = self.pos _tmp = apply(:_Alphanumeric) self.pos = _save7 unless _tmp self.pos = _save6 end break end # end sequence break if _tmp self.pos = _save5 break end # end choice break unless _tmp end _tmp = true else self.pos = _save1 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_StrChunk unless _tmp return _tmp end # EscapedChar = "\\" !@Newline < /[:\\`|*_{}\[\]()#+.!><-]/ > { text } def _EscapedChar _save = self.pos while true # sequence _tmp = match_string("\\") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = _Newline() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _text_start = self.pos _tmp = scan(/\G(?-mix:[:\\`|*_{}\[\]()#+.!><-])/) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_EscapedChar unless _tmp return _tmp end # Entity = (HexEntity | DecEntity | CharEntity):a { a } def _Entity _save = self.pos while true # sequence _save1 = self.pos while true # choice _tmp = apply(:_HexEntity) break if _tmp self.pos = _save1 _tmp = apply(:_DecEntity) break if _tmp self.pos = _save1 _tmp = apply(:_CharEntity) break if _tmp self.pos = _save1 break end # end choice a = @result unless _tmp self.pos = _save break end @result = begin; a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Entity unless _tmp return _tmp end # Endline = (@LineBreak | @TerminalEndline | @NormalEndline) def _Endline _save = self.pos while true # choice _tmp = _LineBreak() break if _tmp self.pos = _save _tmp = _TerminalEndline() break if _tmp self.pos = _save _tmp = _NormalEndline() break if _tmp self.pos = _save break end # end choice set_failed_rule :_Endline unless _tmp return _tmp end # NormalEndline = @Sp @Newline !@BlankLine !">" !AtxStart !(Line /={1,}|-{1,}/ @Newline) { "\n" } def _NormalEndline _save = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end _save1 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _save2 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save2 unless _tmp self.pos = _save break end _save3 = self.pos _tmp = apply(:_AtxStart) _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save break end _save4 = self.pos _save5 = self.pos while true # sequence _tmp = apply(:_Line) unless _tmp self.pos = _save5 break end _tmp = scan(/\G(?-mix:={1,}|-{1,})/) unless _tmp self.pos = _save5 break end _tmp = _Newline() unless _tmp self.pos = _save5 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save break end @result = begin; "\n" ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_NormalEndline unless _tmp return _tmp end # TerminalEndline = @Sp @Newline @Eof def _TerminalEndline _save = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end _tmp = _Eof() unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TerminalEndline unless _tmp return _tmp end # LineBreak = " " @NormalEndline { RDoc::Markup::HardBreak.new } def _LineBreak _save = self.pos while true # sequence _tmp = match_string(" ") unless _tmp self.pos = _save break end _tmp = _NormalEndline() unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::HardBreak.new ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_LineBreak unless _tmp return _tmp end # Symbol = < @SpecialChar > { text } def _Symbol _save = self.pos while true # sequence _text_start = self.pos _tmp = _SpecialChar() if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Symbol unless _tmp return _tmp end # UlOrStarLine = (UlLine | StarLine):a { a } def _UlOrStarLine _save = self.pos while true # sequence _save1 = self.pos while true # choice _tmp = apply(:_UlLine) break if _tmp self.pos = _save1 _tmp = apply(:_StarLine) break if _tmp self.pos = _save1 break end # end choice a = @result unless _tmp self.pos = _save break end @result = begin; a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_UlOrStarLine unless _tmp return _tmp end # StarLine = (< /\*{4,}/ > { text } | < @Spacechar /\*+/ &@Spacechar > { text }) def _StarLine _save = self.pos while true # choice _save1 = self.pos while true # sequence _text_start = self.pos _tmp = scan(/\G(?-mix:\*{4,})/) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save1 break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save1 end break end # end sequence break if _tmp self.pos = _save _save2 = self.pos while true # sequence _text_start = self.pos _save3 = self.pos while true # sequence _tmp = _Spacechar() unless _tmp self.pos = _save3 break end _tmp = scan(/\G(?-mix:\*+)/) unless _tmp self.pos = _save3 break end _save4 = self.pos _tmp = _Spacechar() self.pos = _save4 unless _tmp self.pos = _save3 end break end # end sequence if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save2 break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save2 end break end # end sequence break if _tmp self.pos = _save break end # end choice set_failed_rule :_StarLine unless _tmp return _tmp end # UlLine = (< /_{4,}/ > { text } | < @Spacechar /_+/ &@Spacechar > { text }) def _UlLine _save = self.pos while true # choice _save1 = self.pos while true # sequence _text_start = self.pos _tmp = scan(/\G(?-mix:_{4,})/) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save1 break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save1 end break end # end sequence break if _tmp self.pos = _save _save2 = self.pos while true # sequence _text_start = self.pos _save3 = self.pos while true # sequence _tmp = _Spacechar() unless _tmp self.pos = _save3 break end _tmp = scan(/\G(?-mix:_+)/) unless _tmp self.pos = _save3 break end _save4 = self.pos _tmp = _Spacechar() self.pos = _save4 unless _tmp self.pos = _save3 end break end # end sequence if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save2 break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save2 end break end # end sequence break if _tmp self.pos = _save break end # end choice set_failed_rule :_UlLine unless _tmp return _tmp end # Emph = (EmphStar | EmphUl) def _Emph _save = self.pos while true # choice _tmp = apply(:_EmphStar) break if _tmp self.pos = _save _tmp = apply(:_EmphUl) break if _tmp self.pos = _save break end # end choice set_failed_rule :_Emph unless _tmp return _tmp end # Whitespace = (@Spacechar | @Newline) def _Whitespace _save = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save _tmp = _Newline() break if _tmp self.pos = _save break end # end choice set_failed_rule :_Whitespace unless _tmp return _tmp end # EmphStar = "*" !@Whitespace @StartList:a (!"*" Inline:b { a << b } | StrongStar:b { a << b })+ "*" { emphasis a.join } def _EmphStar _save = self.pos while true # sequence _tmp = match_string("*") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = _Whitespace() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # choice _save4 = self.pos while true # sequence _save5 = self.pos _tmp = match_string("*") _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save4 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save4 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save4 end break end # end sequence break if _tmp self.pos = _save3 _save6 = self.pos while true # sequence _tmp = apply(:_StrongStar) b = @result unless _tmp self.pos = _save6 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save6 end break end # end sequence break if _tmp self.pos = _save3 break end # end choice if _tmp while true _save7 = self.pos while true # choice _save8 = self.pos while true # sequence _save9 = self.pos _tmp = match_string("*") _tmp = _tmp ? nil : true self.pos = _save9 unless _tmp self.pos = _save8 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save8 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save8 end break end # end sequence break if _tmp self.pos = _save7 _save10 = self.pos while true # sequence _tmp = apply(:_StrongStar) b = @result unless _tmp self.pos = _save10 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save10 end break end # end sequence break if _tmp self.pos = _save7 break end # end choice break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save break end _tmp = match_string("*") unless _tmp self.pos = _save break end @result = begin; emphasis a.join ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_EmphStar unless _tmp return _tmp end # EmphUl = "_" !@Whitespace @StartList:a (!"_" Inline:b { a << b } | StrongUl:b { a << b })+ "_" { emphasis a.join } def _EmphUl _save = self.pos while true # sequence _tmp = match_string("_") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = _Whitespace() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # choice _save4 = self.pos while true # sequence _save5 = self.pos _tmp = match_string("_") _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save4 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save4 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save4 end break end # end sequence break if _tmp self.pos = _save3 _save6 = self.pos while true # sequence _tmp = apply(:_StrongUl) b = @result unless _tmp self.pos = _save6 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save6 end break end # end sequence break if _tmp self.pos = _save3 break end # end choice if _tmp while true _save7 = self.pos while true # choice _save8 = self.pos while true # sequence _save9 = self.pos _tmp = match_string("_") _tmp = _tmp ? nil : true self.pos = _save9 unless _tmp self.pos = _save8 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save8 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save8 end break end # end sequence break if _tmp self.pos = _save7 _save10 = self.pos while true # sequence _tmp = apply(:_StrongUl) b = @result unless _tmp self.pos = _save10 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save10 end break end # end sequence break if _tmp self.pos = _save7 break end # end choice break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save break end _tmp = match_string("_") unless _tmp self.pos = _save break end @result = begin; emphasis a.join ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_EmphUl unless _tmp return _tmp end # Strong = (StrongStar | StrongUl) def _Strong _save = self.pos while true # choice _tmp = apply(:_StrongStar) break if _tmp self.pos = _save _tmp = apply(:_StrongUl) break if _tmp self.pos = _save break end # end choice set_failed_rule :_Strong unless _tmp return _tmp end # StrongStar = "**" !@Whitespace @StartList:a (!"**" Inline:b { a << b })+ "**" { strong a.join } def _StrongStar _save = self.pos while true # sequence _tmp = match_string("**") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = _Whitespace() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # sequence _save4 = self.pos _tmp = match_string("**") _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save3 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save3 end break end # end sequence if _tmp while true _save5 = self.pos while true # sequence _save6 = self.pos _tmp = match_string("**") _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save5 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save5 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save5 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save break end _tmp = match_string("**") unless _tmp self.pos = _save break end @result = begin; strong a.join ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_StrongStar unless _tmp return _tmp end # StrongUl = "__" !@Whitespace @StartList:a (!"__" Inline:b { a << b })+ "__" { strong a.join } def _StrongUl _save = self.pos while true # sequence _tmp = match_string("__") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = _Whitespace() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # sequence _save4 = self.pos _tmp = match_string("__") _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save3 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save3 end break end # end sequence if _tmp while true _save5 = self.pos while true # sequence _save6 = self.pos _tmp = match_string("__") _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save5 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save5 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save5 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save break end _tmp = match_string("__") unless _tmp self.pos = _save break end @result = begin; strong a.join ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_StrongUl unless _tmp return _tmp end # Strike = &{ strike? } "~~" !@Whitespace @StartList:a (!"~~" Inline:b { a << b })+ "~~" { strike a.join } def _Strike _save = self.pos while true # sequence _save1 = self.pos _tmp = begin; strike? ; end self.pos = _save1 unless _tmp self.pos = _save break end _tmp = match_string("~~") unless _tmp self.pos = _save break end _save2 = self.pos _tmp = _Whitespace() _tmp = _tmp ? nil : true self.pos = _save2 unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save3 = self.pos _save4 = self.pos while true # sequence _save5 = self.pos _tmp = match_string("~~") _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save4 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save4 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save4 end break end # end sequence if _tmp while true _save6 = self.pos while true # sequence _save7 = self.pos _tmp = match_string("~~") _tmp = _tmp ? nil : true self.pos = _save7 unless _tmp self.pos = _save6 break end _tmp = apply(:_Inline) b = @result unless _tmp self.pos = _save6 break end @result = begin; a << b ; end _tmp = true unless _tmp self.pos = _save6 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save3 end unless _tmp self.pos = _save break end _tmp = match_string("~~") unless _tmp self.pos = _save break end @result = begin; strike a.join ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Strike unless _tmp return _tmp end # Image = "!" (ExplicitLink | ReferenceLink):a { "rdoc-image:#{a[/\[(.*)\]/, 1]}" } def _Image _save = self.pos while true # sequence _tmp = match_string("!") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _tmp = apply(:_ExplicitLink) break if _tmp self.pos = _save1 _tmp = apply(:_ReferenceLink) break if _tmp self.pos = _save1 break end # end choice a = @result unless _tmp self.pos = _save break end @result = begin; "rdoc-image:#{a[/\[(.*)\]/, 1]}" ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Image unless _tmp return _tmp end # Link = (ExplicitLink | ReferenceLink | AutoLink) def _Link _save = self.pos while true # choice _tmp = apply(:_ExplicitLink) break if _tmp self.pos = _save _tmp = apply(:_ReferenceLink) break if _tmp self.pos = _save _tmp = apply(:_AutoLink) break if _tmp self.pos = _save break end # end choice set_failed_rule :_Link unless _tmp return _tmp end # ReferenceLink = (ReferenceLinkDouble | ReferenceLinkSingle) def _ReferenceLink _save = self.pos while true # choice _tmp = apply(:_ReferenceLinkDouble) break if _tmp self.pos = _save _tmp = apply(:_ReferenceLinkSingle) break if _tmp self.pos = _save break end # end choice set_failed_rule :_ReferenceLink unless _tmp return _tmp end # ReferenceLinkDouble = Label:content < Spnl > !"[]" Label:label { link_to content, label, text } def _ReferenceLinkDouble _save = self.pos while true # sequence _tmp = apply(:_Label) content = @result unless _tmp self.pos = _save break end _text_start = self.pos _tmp = apply(:_Spnl) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _save1 = self.pos _tmp = match_string("[]") _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _tmp = apply(:_Label) label = @result unless _tmp self.pos = _save break end @result = begin; link_to content, label, text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ReferenceLinkDouble unless _tmp return _tmp end # ReferenceLinkSingle = Label:content < (Spnl "[]")? > { link_to content, content, text } def _ReferenceLinkSingle _save = self.pos while true # sequence _tmp = apply(:_Label) content = @result unless _tmp self.pos = _save break end _text_start = self.pos _save1 = self.pos _save2 = self.pos while true # sequence _tmp = apply(:_Spnl) unless _tmp self.pos = _save2 break end _tmp = match_string("[]") unless _tmp self.pos = _save2 end break end # end sequence unless _tmp _tmp = true self.pos = _save1 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; link_to content, content, text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ReferenceLinkSingle unless _tmp return _tmp end # ExplicitLink = Label:l "(" @Sp Source:s Spnl Title @Sp ")" { "{#{l}}[#{s}]" } def _ExplicitLink _save = self.pos while true # sequence _tmp = apply(:_Label) l = @result unless _tmp self.pos = _save break end _tmp = match_string("(") unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = apply(:_Source) s = @result unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = apply(:_Title) unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = match_string(")") unless _tmp self.pos = _save break end @result = begin; "{#{l}}[#{s}]" ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ExplicitLink unless _tmp return _tmp end # Source = ("<" < SourceContents > ">" | < SourceContents >) { text } def _Source _save = self.pos while true # sequence _save1 = self.pos while true # choice _save2 = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save2 break end _text_start = self.pos _tmp = apply(:_SourceContents) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save2 break end _tmp = match_string(">") unless _tmp self.pos = _save2 end break end # end sequence break if _tmp self.pos = _save1 _text_start = self.pos _tmp = apply(:_SourceContents) if _tmp text = get_text(_text_start) end break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Source unless _tmp return _tmp end # SourceContents = ((!"(" !")" !">" Nonspacechar)+ | "(" SourceContents ")")* def _SourceContents while true _save1 = self.pos while true # choice _save2 = self.pos _save3 = self.pos while true # sequence _save4 = self.pos _tmp = match_string("(") _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _save5 = self.pos _tmp = match_string(")") _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save3 break end _save6 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save3 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save3 end break end # end sequence if _tmp while true _save7 = self.pos while true # sequence _save8 = self.pos _tmp = match_string("(") _tmp = _tmp ? nil : true self.pos = _save8 unless _tmp self.pos = _save7 break end _save9 = self.pos _tmp = match_string(")") _tmp = _tmp ? nil : true self.pos = _save9 unless _tmp self.pos = _save7 break end _save10 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save10 unless _tmp self.pos = _save7 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save7 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save2 end break if _tmp self.pos = _save1 _save11 = self.pos while true # sequence _tmp = match_string("(") unless _tmp self.pos = _save11 break end _tmp = apply(:_SourceContents) unless _tmp self.pos = _save11 break end _tmp = match_string(")") unless _tmp self.pos = _save11 end break end # end sequence break if _tmp self.pos = _save1 break end # end choice break unless _tmp end _tmp = true set_failed_rule :_SourceContents unless _tmp return _tmp end # Title = (TitleSingle | TitleDouble | ""):a { a } def _Title _save = self.pos while true # sequence _save1 = self.pos while true # choice _tmp = apply(:_TitleSingle) break if _tmp self.pos = _save1 _tmp = apply(:_TitleDouble) break if _tmp self.pos = _save1 _tmp = match_string("") break if _tmp self.pos = _save1 break end # end choice a = @result unless _tmp self.pos = _save break end @result = begin; a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Title unless _tmp return _tmp end # TitleSingle = "'" (!("'" @Sp (")" | @Newline)) .)* "'" def _TitleSingle _save = self.pos while true # sequence _tmp = match_string("'") unless _tmp self.pos = _save break end while true _save2 = self.pos while true # sequence _save3 = self.pos _save4 = self.pos while true # sequence _tmp = match_string("'") unless _tmp self.pos = _save4 break end _tmp = _Sp() unless _tmp self.pos = _save4 break end _save5 = self.pos while true # choice _tmp = match_string(")") break if _tmp self.pos = _save5 _tmp = _Newline() break if _tmp self.pos = _save5 break end # end choice unless _tmp self.pos = _save4 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string("'") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TitleSingle unless _tmp return _tmp end # TitleDouble = "\"" (!("\"" @Sp (")" | @Newline)) .)* "\"" def _TitleDouble _save = self.pos while true # sequence _tmp = match_string("\"") unless _tmp self.pos = _save break end while true _save2 = self.pos while true # sequence _save3 = self.pos _save4 = self.pos while true # sequence _tmp = match_string("\"") unless _tmp self.pos = _save4 break end _tmp = _Sp() unless _tmp self.pos = _save4 break end _save5 = self.pos while true # choice _tmp = match_string(")") break if _tmp self.pos = _save5 _tmp = _Newline() break if _tmp self.pos = _save5 break end # end choice unless _tmp self.pos = _save4 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string("\"") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TitleDouble unless _tmp return _tmp end # AutoLink = (AutoLinkUrl | AutoLinkEmail) def _AutoLink _save = self.pos while true # choice _tmp = apply(:_AutoLinkUrl) break if _tmp self.pos = _save _tmp = apply(:_AutoLinkEmail) break if _tmp self.pos = _save break end # end choice set_failed_rule :_AutoLink unless _tmp return _tmp end # AutoLinkUrl = "<" < /[A-Za-z]+/ "://" (!@Newline !">" .)+ > ">" { text } def _AutoLinkUrl _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _text_start = self.pos _save1 = self.pos while true # sequence _tmp = scan(/\G(?-mix:[A-Za-z]+)/) unless _tmp self.pos = _save1 break end _tmp = match_string("://") unless _tmp self.pos = _save1 break end _save2 = self.pos _save3 = self.pos while true # sequence _save4 = self.pos _tmp = _Newline() _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _save5 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence if _tmp while true _save6 = self.pos while true # sequence _save7 = self.pos _tmp = _Newline() _tmp = _tmp ? nil : true self.pos = _save7 unless _tmp self.pos = _save6 break end _save8 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save8 unless _tmp self.pos = _save6 break end _tmp = get_byte unless _tmp self.pos = _save6 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save1 end break end # end sequence if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_AutoLinkUrl unless _tmp return _tmp end # AutoLinkEmail = "<" "mailto:"? < /[\w+.\/!%~$-]+/i "@" (!@Newline !">" .)+ > ">" { "mailto:#{text}" } def _AutoLinkEmail _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = match_string("mailto:") unless _tmp _tmp = true self.pos = _save1 end unless _tmp self.pos = _save break end _text_start = self.pos _save2 = self.pos while true # sequence _tmp = scan(/\G(?i-mx:[\w+.\/!%~$-]+)/) unless _tmp self.pos = _save2 break end _tmp = match_string("@") unless _tmp self.pos = _save2 break end _save3 = self.pos _save4 = self.pos while true # sequence _save5 = self.pos _tmp = _Newline() _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save4 break end _save6 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save4 break end _tmp = get_byte unless _tmp self.pos = _save4 end break end # end sequence if _tmp while true _save7 = self.pos while true # sequence _save8 = self.pos _tmp = _Newline() _tmp = _tmp ? nil : true self.pos = _save8 unless _tmp self.pos = _save7 break end _save9 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save9 unless _tmp self.pos = _save7 break end _tmp = get_byte unless _tmp self.pos = _save7 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save3 end unless _tmp self.pos = _save2 end break end # end sequence if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save break end @result = begin; "mailto:#{text}" ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_AutoLinkEmail unless _tmp return _tmp end # Reference = @NonindentSpace !"[]" Label:label ":" Spnl RefSrc:link RefTitle @BlankLine+ { # TODO use title reference label, link nil } def _Reference _save = self.pos while true # sequence _tmp = _NonindentSpace() unless _tmp self.pos = _save break end _save1 = self.pos _tmp = match_string("[]") _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _tmp = apply(:_Label) label = @result unless _tmp self.pos = _save break end _tmp = match_string(":") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = apply(:_RefSrc) link = @result unless _tmp self.pos = _save break end _tmp = apply(:_RefTitle) unless _tmp self.pos = _save break end _save2 = self.pos _tmp = _BlankLine() if _tmp while true _tmp = _BlankLine() break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save break end @result = begin; # TODO use title reference label, link nil ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Reference unless _tmp return _tmp end # Label = "[" (!"^" &{ notes? } | &. &{ !notes? }) @StartList:a (!"]" Inline:l { a << l })* "]" { a.join.gsub(/\s+/, ' ') } def _Label _save = self.pos while true # sequence _tmp = match_string("[") unless _tmp self.pos = _save break end _save1 = self.pos while true # choice _save2 = self.pos while true # sequence _save3 = self.pos _tmp = match_string("^") _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _save4 = self.pos _tmp = begin; notes? ; end self.pos = _save4 unless _tmp self.pos = _save2 end break end # end sequence break if _tmp self.pos = _save1 _save5 = self.pos while true # sequence _save6 = self.pos _tmp = get_byte self.pos = _save6 unless _tmp self.pos = _save5 break end _save7 = self.pos _tmp = begin; !notes? ; end self.pos = _save7 unless _tmp self.pos = _save5 end break end # end sequence break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end while true _save9 = self.pos while true # sequence _save10 = self.pos _tmp = match_string("]") _tmp = _tmp ? nil : true self.pos = _save10 unless _tmp self.pos = _save9 break end _tmp = apply(:_Inline) l = @result unless _tmp self.pos = _save9 break end @result = begin; a << l ; end _tmp = true unless _tmp self.pos = _save9 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string("]") unless _tmp self.pos = _save break end @result = begin; a.join.gsub(/\s+/, ' ') ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Label unless _tmp return _tmp end # RefSrc = < Nonspacechar+ > { text } def _RefSrc _save = self.pos while true # sequence _text_start = self.pos _save1 = self.pos _tmp = apply(:_Nonspacechar) if _tmp while true _tmp = apply(:_Nonspacechar) break unless _tmp end _tmp = true else self.pos = _save1 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_RefSrc unless _tmp return _tmp end # RefTitle = (RefTitleSingle | RefTitleDouble | RefTitleParens | EmptyTitle) def _RefTitle _save = self.pos while true # choice _tmp = apply(:_RefTitleSingle) break if _tmp self.pos = _save _tmp = apply(:_RefTitleDouble) break if _tmp self.pos = _save _tmp = apply(:_RefTitleParens) break if _tmp self.pos = _save _tmp = apply(:_EmptyTitle) break if _tmp self.pos = _save break end # end choice set_failed_rule :_RefTitle unless _tmp return _tmp end # EmptyTitle = "" def _EmptyTitle _tmp = match_string("") set_failed_rule :_EmptyTitle unless _tmp return _tmp end # RefTitleSingle = Spnl "'" < (!("'" @Sp @Newline | @Newline) .)* > "'" { text } def _RefTitleSingle _save = self.pos while true # sequence _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("'") unless _tmp self.pos = _save break end _text_start = self.pos while true _save2 = self.pos while true # sequence _save3 = self.pos _save4 = self.pos while true # choice _save5 = self.pos while true # sequence _tmp = match_string("'") unless _tmp self.pos = _save5 break end _tmp = _Sp() unless _tmp self.pos = _save5 break end _tmp = _Newline() unless _tmp self.pos = _save5 end break end # end sequence break if _tmp self.pos = _save4 _tmp = _Newline() break if _tmp self.pos = _save4 break end # end choice _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence break unless _tmp end _tmp = true if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = match_string("'") unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_RefTitleSingle unless _tmp return _tmp end # RefTitleDouble = Spnl "\"" < (!("\"" @Sp @Newline | @Newline) .)* > "\"" { text } def _RefTitleDouble _save = self.pos while true # sequence _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("\"") unless _tmp self.pos = _save break end _text_start = self.pos while true _save2 = self.pos while true # sequence _save3 = self.pos _save4 = self.pos while true # choice _save5 = self.pos while true # sequence _tmp = match_string("\"") unless _tmp self.pos = _save5 break end _tmp = _Sp() unless _tmp self.pos = _save5 break end _tmp = _Newline() unless _tmp self.pos = _save5 end break end # end sequence break if _tmp self.pos = _save4 _tmp = _Newline() break if _tmp self.pos = _save4 break end # end choice _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence break unless _tmp end _tmp = true if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = match_string("\"") unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_RefTitleDouble unless _tmp return _tmp end # RefTitleParens = Spnl "(" < (!(")" @Sp @Newline | @Newline) .)* > ")" { text } def _RefTitleParens _save = self.pos while true # sequence _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string("(") unless _tmp self.pos = _save break end _text_start = self.pos while true _save2 = self.pos while true # sequence _save3 = self.pos _save4 = self.pos while true # choice _save5 = self.pos while true # sequence _tmp = match_string(")") unless _tmp self.pos = _save5 break end _tmp = _Sp() unless _tmp self.pos = _save5 break end _tmp = _Newline() unless _tmp self.pos = _save5 end break end # end sequence break if _tmp self.pos = _save4 _tmp = _Newline() break if _tmp self.pos = _save4 break end # end choice _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence break unless _tmp end _tmp = true if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = match_string(")") unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_RefTitleParens unless _tmp return _tmp end # References = (Reference | SkipBlock)* def _References while true _save1 = self.pos while true # choice _tmp = apply(:_Reference) break if _tmp self.pos = _save1 _tmp = apply(:_SkipBlock) break if _tmp self.pos = _save1 break end # end choice break unless _tmp end _tmp = true set_failed_rule :_References unless _tmp return _tmp end # Ticks1 = "`" !"`" def _Ticks1 _save = self.pos while true # sequence _tmp = match_string("`") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Ticks1 unless _tmp return _tmp end # Ticks2 = "``" !"`" def _Ticks2 _save = self.pos while true # sequence _tmp = match_string("``") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Ticks2 unless _tmp return _tmp end # Ticks3 = "```" !"`" def _Ticks3 _save = self.pos while true # sequence _tmp = match_string("```") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Ticks3 unless _tmp return _tmp end # Ticks4 = "````" !"`" def _Ticks4 _save = self.pos while true # sequence _tmp = match_string("````") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Ticks4 unless _tmp return _tmp end # Ticks5 = "`````" !"`" def _Ticks5 _save = self.pos while true # sequence _tmp = match_string("`````") unless _tmp self.pos = _save break end _save1 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Ticks5 unless _tmp return _tmp end # Code = (Ticks1 @Sp < ((!"`" Nonspacechar)+ | !Ticks1 /`+/ | !(@Sp Ticks1) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks1 | Ticks2 @Sp < ((!"`" Nonspacechar)+ | !Ticks2 /`+/ | !(@Sp Ticks2) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks2 | Ticks3 @Sp < ((!"`" Nonspacechar)+ | !Ticks3 /`+/ | !(@Sp Ticks3) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks3 | Ticks4 @Sp < ((!"`" Nonspacechar)+ | !Ticks4 /`+/ | !(@Sp Ticks4) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks4 | Ticks5 @Sp < ((!"`" Nonspacechar)+ | !Ticks5 /`+/ | !(@Sp Ticks5) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks5) { "#{text}" } def _Code _save = self.pos while true # sequence _save1 = self.pos while true # choice _save2 = self.pos while true # sequence _tmp = apply(:_Ticks1) unless _tmp self.pos = _save2 break end _tmp = _Sp() unless _tmp self.pos = _save2 break end _text_start = self.pos _save3 = self.pos _save4 = self.pos while true # choice _save5 = self.pos _save6 = self.pos while true # sequence _save7 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save7 unless _tmp self.pos = _save6 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save6 end break end # end sequence if _tmp while true _save8 = self.pos while true # sequence _save9 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save9 unless _tmp self.pos = _save8 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save8 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save5 end break if _tmp self.pos = _save4 _save10 = self.pos while true # sequence _save11 = self.pos _tmp = apply(:_Ticks1) _tmp = _tmp ? nil : true self.pos = _save11 unless _tmp self.pos = _save10 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save10 end break end # end sequence break if _tmp self.pos = _save4 _save12 = self.pos while true # sequence _save13 = self.pos _save14 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save14 break end _tmp = apply(:_Ticks1) unless _tmp self.pos = _save14 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save13 unless _tmp self.pos = _save12 break end _save15 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save15 _save16 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save16 break end _save17 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save17 unless _tmp self.pos = _save16 end break end # end sequence break if _tmp self.pos = _save15 break end # end choice unless _tmp self.pos = _save12 end break end # end sequence break if _tmp self.pos = _save4 break end # end choice if _tmp while true _save18 = self.pos while true # choice _save19 = self.pos _save20 = self.pos while true # sequence _save21 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save21 unless _tmp self.pos = _save20 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save20 end break end # end sequence if _tmp while true _save22 = self.pos while true # sequence _save23 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save23 unless _tmp self.pos = _save22 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save22 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save19 end break if _tmp self.pos = _save18 _save24 = self.pos while true # sequence _save25 = self.pos _tmp = apply(:_Ticks1) _tmp = _tmp ? nil : true self.pos = _save25 unless _tmp self.pos = _save24 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save24 end break end # end sequence break if _tmp self.pos = _save18 _save26 = self.pos while true # sequence _save27 = self.pos _save28 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save28 break end _tmp = apply(:_Ticks1) unless _tmp self.pos = _save28 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save27 unless _tmp self.pos = _save26 break end _save29 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save29 _save30 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save30 break end _save31 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save31 unless _tmp self.pos = _save30 end break end # end sequence break if _tmp self.pos = _save29 break end # end choice unless _tmp self.pos = _save26 end break end # end sequence break if _tmp self.pos = _save18 break end # end choice break unless _tmp end _tmp = true else self.pos = _save3 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save2 break end _tmp = _Sp() unless _tmp self.pos = _save2 break end _tmp = apply(:_Ticks1) unless _tmp self.pos = _save2 end break end # end sequence break if _tmp self.pos = _save1 _save32 = self.pos while true # sequence _tmp = apply(:_Ticks2) unless _tmp self.pos = _save32 break end _tmp = _Sp() unless _tmp self.pos = _save32 break end _text_start = self.pos _save33 = self.pos _save34 = self.pos while true # choice _save35 = self.pos _save36 = self.pos while true # sequence _save37 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save37 unless _tmp self.pos = _save36 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save36 end break end # end sequence if _tmp while true _save38 = self.pos while true # sequence _save39 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save39 unless _tmp self.pos = _save38 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save38 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save35 end break if _tmp self.pos = _save34 _save40 = self.pos while true # sequence _save41 = self.pos _tmp = apply(:_Ticks2) _tmp = _tmp ? nil : true self.pos = _save41 unless _tmp self.pos = _save40 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save40 end break end # end sequence break if _tmp self.pos = _save34 _save42 = self.pos while true # sequence _save43 = self.pos _save44 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save44 break end _tmp = apply(:_Ticks2) unless _tmp self.pos = _save44 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save43 unless _tmp self.pos = _save42 break end _save45 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save45 _save46 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save46 break end _save47 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save47 unless _tmp self.pos = _save46 end break end # end sequence break if _tmp self.pos = _save45 break end # end choice unless _tmp self.pos = _save42 end break end # end sequence break if _tmp self.pos = _save34 break end # end choice if _tmp while true _save48 = self.pos while true # choice _save49 = self.pos _save50 = self.pos while true # sequence _save51 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save51 unless _tmp self.pos = _save50 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save50 end break end # end sequence if _tmp while true _save52 = self.pos while true # sequence _save53 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save53 unless _tmp self.pos = _save52 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save52 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save49 end break if _tmp self.pos = _save48 _save54 = self.pos while true # sequence _save55 = self.pos _tmp = apply(:_Ticks2) _tmp = _tmp ? nil : true self.pos = _save55 unless _tmp self.pos = _save54 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save54 end break end # end sequence break if _tmp self.pos = _save48 _save56 = self.pos while true # sequence _save57 = self.pos _save58 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save58 break end _tmp = apply(:_Ticks2) unless _tmp self.pos = _save58 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save57 unless _tmp self.pos = _save56 break end _save59 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save59 _save60 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save60 break end _save61 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save61 unless _tmp self.pos = _save60 end break end # end sequence break if _tmp self.pos = _save59 break end # end choice unless _tmp self.pos = _save56 end break end # end sequence break if _tmp self.pos = _save48 break end # end choice break unless _tmp end _tmp = true else self.pos = _save33 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save32 break end _tmp = _Sp() unless _tmp self.pos = _save32 break end _tmp = apply(:_Ticks2) unless _tmp self.pos = _save32 end break end # end sequence break if _tmp self.pos = _save1 _save62 = self.pos while true # sequence _tmp = apply(:_Ticks3) unless _tmp self.pos = _save62 break end _tmp = _Sp() unless _tmp self.pos = _save62 break end _text_start = self.pos _save63 = self.pos _save64 = self.pos while true # choice _save65 = self.pos _save66 = self.pos while true # sequence _save67 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save67 unless _tmp self.pos = _save66 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save66 end break end # end sequence if _tmp while true _save68 = self.pos while true # sequence _save69 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save69 unless _tmp self.pos = _save68 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save68 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save65 end break if _tmp self.pos = _save64 _save70 = self.pos while true # sequence _save71 = self.pos _tmp = apply(:_Ticks3) _tmp = _tmp ? nil : true self.pos = _save71 unless _tmp self.pos = _save70 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save70 end break end # end sequence break if _tmp self.pos = _save64 _save72 = self.pos while true # sequence _save73 = self.pos _save74 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save74 break end _tmp = apply(:_Ticks3) unless _tmp self.pos = _save74 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save73 unless _tmp self.pos = _save72 break end _save75 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save75 _save76 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save76 break end _save77 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save77 unless _tmp self.pos = _save76 end break end # end sequence break if _tmp self.pos = _save75 break end # end choice unless _tmp self.pos = _save72 end break end # end sequence break if _tmp self.pos = _save64 break end # end choice if _tmp while true _save78 = self.pos while true # choice _save79 = self.pos _save80 = self.pos while true # sequence _save81 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save81 unless _tmp self.pos = _save80 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save80 end break end # end sequence if _tmp while true _save82 = self.pos while true # sequence _save83 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save83 unless _tmp self.pos = _save82 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save82 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save79 end break if _tmp self.pos = _save78 _save84 = self.pos while true # sequence _save85 = self.pos _tmp = apply(:_Ticks3) _tmp = _tmp ? nil : true self.pos = _save85 unless _tmp self.pos = _save84 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save84 end break end # end sequence break if _tmp self.pos = _save78 _save86 = self.pos while true # sequence _save87 = self.pos _save88 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save88 break end _tmp = apply(:_Ticks3) unless _tmp self.pos = _save88 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save87 unless _tmp self.pos = _save86 break end _save89 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save89 _save90 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save90 break end _save91 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save91 unless _tmp self.pos = _save90 end break end # end sequence break if _tmp self.pos = _save89 break end # end choice unless _tmp self.pos = _save86 end break end # end sequence break if _tmp self.pos = _save78 break end # end choice break unless _tmp end _tmp = true else self.pos = _save63 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save62 break end _tmp = _Sp() unless _tmp self.pos = _save62 break end _tmp = apply(:_Ticks3) unless _tmp self.pos = _save62 end break end # end sequence break if _tmp self.pos = _save1 _save92 = self.pos while true # sequence _tmp = apply(:_Ticks4) unless _tmp self.pos = _save92 break end _tmp = _Sp() unless _tmp self.pos = _save92 break end _text_start = self.pos _save93 = self.pos _save94 = self.pos while true # choice _save95 = self.pos _save96 = self.pos while true # sequence _save97 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save97 unless _tmp self.pos = _save96 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save96 end break end # end sequence if _tmp while true _save98 = self.pos while true # sequence _save99 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save99 unless _tmp self.pos = _save98 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save98 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save95 end break if _tmp self.pos = _save94 _save100 = self.pos while true # sequence _save101 = self.pos _tmp = apply(:_Ticks4) _tmp = _tmp ? nil : true self.pos = _save101 unless _tmp self.pos = _save100 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save100 end break end # end sequence break if _tmp self.pos = _save94 _save102 = self.pos while true # sequence _save103 = self.pos _save104 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save104 break end _tmp = apply(:_Ticks4) unless _tmp self.pos = _save104 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save103 unless _tmp self.pos = _save102 break end _save105 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save105 _save106 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save106 break end _save107 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save107 unless _tmp self.pos = _save106 end break end # end sequence break if _tmp self.pos = _save105 break end # end choice unless _tmp self.pos = _save102 end break end # end sequence break if _tmp self.pos = _save94 break end # end choice if _tmp while true _save108 = self.pos while true # choice _save109 = self.pos _save110 = self.pos while true # sequence _save111 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save111 unless _tmp self.pos = _save110 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save110 end break end # end sequence if _tmp while true _save112 = self.pos while true # sequence _save113 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save113 unless _tmp self.pos = _save112 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save112 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save109 end break if _tmp self.pos = _save108 _save114 = self.pos while true # sequence _save115 = self.pos _tmp = apply(:_Ticks4) _tmp = _tmp ? nil : true self.pos = _save115 unless _tmp self.pos = _save114 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save114 end break end # end sequence break if _tmp self.pos = _save108 _save116 = self.pos while true # sequence _save117 = self.pos _save118 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save118 break end _tmp = apply(:_Ticks4) unless _tmp self.pos = _save118 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save117 unless _tmp self.pos = _save116 break end _save119 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save119 _save120 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save120 break end _save121 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save121 unless _tmp self.pos = _save120 end break end # end sequence break if _tmp self.pos = _save119 break end # end choice unless _tmp self.pos = _save116 end break end # end sequence break if _tmp self.pos = _save108 break end # end choice break unless _tmp end _tmp = true else self.pos = _save93 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save92 break end _tmp = _Sp() unless _tmp self.pos = _save92 break end _tmp = apply(:_Ticks4) unless _tmp self.pos = _save92 end break end # end sequence break if _tmp self.pos = _save1 _save122 = self.pos while true # sequence _tmp = apply(:_Ticks5) unless _tmp self.pos = _save122 break end _tmp = _Sp() unless _tmp self.pos = _save122 break end _text_start = self.pos _save123 = self.pos _save124 = self.pos while true # choice _save125 = self.pos _save126 = self.pos while true # sequence _save127 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save127 unless _tmp self.pos = _save126 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save126 end break end # end sequence if _tmp while true _save128 = self.pos while true # sequence _save129 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save129 unless _tmp self.pos = _save128 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save128 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save125 end break if _tmp self.pos = _save124 _save130 = self.pos while true # sequence _save131 = self.pos _tmp = apply(:_Ticks5) _tmp = _tmp ? nil : true self.pos = _save131 unless _tmp self.pos = _save130 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save130 end break end # end sequence break if _tmp self.pos = _save124 _save132 = self.pos while true # sequence _save133 = self.pos _save134 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save134 break end _tmp = apply(:_Ticks5) unless _tmp self.pos = _save134 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save133 unless _tmp self.pos = _save132 break end _save135 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save135 _save136 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save136 break end _save137 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save137 unless _tmp self.pos = _save136 end break end # end sequence break if _tmp self.pos = _save135 break end # end choice unless _tmp self.pos = _save132 end break end # end sequence break if _tmp self.pos = _save124 break end # end choice if _tmp while true _save138 = self.pos while true # choice _save139 = self.pos _save140 = self.pos while true # sequence _save141 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save141 unless _tmp self.pos = _save140 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save140 end break end # end sequence if _tmp while true _save142 = self.pos while true # sequence _save143 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save143 unless _tmp self.pos = _save142 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save142 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save139 end break if _tmp self.pos = _save138 _save144 = self.pos while true # sequence _save145 = self.pos _tmp = apply(:_Ticks5) _tmp = _tmp ? nil : true self.pos = _save145 unless _tmp self.pos = _save144 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save144 end break end # end sequence break if _tmp self.pos = _save138 _save146 = self.pos while true # sequence _save147 = self.pos _save148 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save148 break end _tmp = apply(:_Ticks5) unless _tmp self.pos = _save148 end break end # end sequence _tmp = _tmp ? nil : true self.pos = _save147 unless _tmp self.pos = _save146 break end _save149 = self.pos while true # choice _tmp = _Spacechar() break if _tmp self.pos = _save149 _save150 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save150 break end _save151 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save151 unless _tmp self.pos = _save150 end break end # end sequence break if _tmp self.pos = _save149 break end # end choice unless _tmp self.pos = _save146 end break end # end sequence break if _tmp self.pos = _save138 break end # end choice break unless _tmp end _tmp = true else self.pos = _save123 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save122 break end _tmp = _Sp() unless _tmp self.pos = _save122 break end _tmp = apply(:_Ticks5) unless _tmp self.pos = _save122 end break end # end sequence break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end @result = begin; "#{text}" ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Code unless _tmp return _tmp end # RawHtml = < (HtmlComment | HtmlBlockScript | HtmlTag) > { if html? then text else '' end } def _RawHtml _save = self.pos while true # sequence _text_start = self.pos _save1 = self.pos while true # choice _tmp = apply(:_HtmlComment) break if _tmp self.pos = _save1 _tmp = apply(:_HtmlBlockScript) break if _tmp self.pos = _save1 _tmp = apply(:_HtmlTag) break if _tmp self.pos = _save1 break end # end choice if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; if html? then text else '' end ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_RawHtml unless _tmp return _tmp end # BlankLine = @Sp @Newline { "\n" } def _BlankLine _save = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end @result = begin; "\n" ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_BlankLine unless _tmp return _tmp end # Quoted = ("\"" (!"\"" .)* "\"" | "'" (!"'" .)* "'") def _Quoted _save = self.pos while true # choice _save1 = self.pos while true # sequence _tmp = match_string("\"") unless _tmp self.pos = _save1 break end while true _save3 = self.pos while true # sequence _save4 = self.pos _tmp = match_string("\"") _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = get_byte unless _tmp self.pos = _save3 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save1 break end _tmp = match_string("\"") unless _tmp self.pos = _save1 end break end # end sequence break if _tmp self.pos = _save _save5 = self.pos while true # sequence _tmp = match_string("'") unless _tmp self.pos = _save5 break end while true _save7 = self.pos while true # sequence _save8 = self.pos _tmp = match_string("'") _tmp = _tmp ? nil : true self.pos = _save8 unless _tmp self.pos = _save7 break end _tmp = get_byte unless _tmp self.pos = _save7 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save5 break end _tmp = match_string("'") unless _tmp self.pos = _save5 end break end # end sequence break if _tmp self.pos = _save break end # end choice set_failed_rule :_Quoted unless _tmp return _tmp end # HtmlAttribute = (AlphanumericAscii | "-")+ Spnl ("=" Spnl (Quoted | (!">" Nonspacechar)+))? Spnl def _HtmlAttribute _save = self.pos while true # sequence _save1 = self.pos _save2 = self.pos while true # choice _tmp = apply(:_AlphanumericAscii) break if _tmp self.pos = _save2 _tmp = match_string("-") break if _tmp self.pos = _save2 break end # end choice if _tmp while true _save3 = self.pos while true # choice _tmp = apply(:_AlphanumericAscii) break if _tmp self.pos = _save3 _tmp = match_string("-") break if _tmp self.pos = _save3 break end # end choice break unless _tmp end _tmp = true else self.pos = _save1 end unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save4 = self.pos _save5 = self.pos while true # sequence _tmp = match_string("=") unless _tmp self.pos = _save5 break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save5 break end _save6 = self.pos while true # choice _tmp = apply(:_Quoted) break if _tmp self.pos = _save6 _save7 = self.pos _save8 = self.pos while true # sequence _save9 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save9 unless _tmp self.pos = _save8 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save8 end break end # end sequence if _tmp while true _save10 = self.pos while true # sequence _save11 = self.pos _tmp = match_string(">") _tmp = _tmp ? nil : true self.pos = _save11 unless _tmp self.pos = _save10 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save10 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save7 end break if _tmp self.pos = _save6 break end # end choice unless _tmp self.pos = _save5 end break end # end sequence unless _tmp _tmp = true self.pos = _save4 end unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlAttribute unless _tmp return _tmp end # HtmlComment = "" .)* "-->" def _HtmlComment _save = self.pos while true # sequence _tmp = match_string("") _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _tmp = match_string("-->") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlComment unless _tmp return _tmp end # HtmlTag = "<" Spnl "/"? AlphanumericAscii+ Spnl HtmlAttribute* "/"? Spnl ">" def _HtmlTag _save = self.pos while true # sequence _tmp = match_string("<") unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _save1 = self.pos _tmp = match_string("/") unless _tmp _tmp = true self.pos = _save1 end unless _tmp self.pos = _save break end _save2 = self.pos _tmp = apply(:_AlphanumericAscii) if _tmp while true _tmp = apply(:_AlphanumericAscii) break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end while true _tmp = apply(:_HtmlAttribute) break unless _tmp end _tmp = true unless _tmp self.pos = _save break end _save4 = self.pos _tmp = match_string("/") unless _tmp _tmp = true self.pos = _save4 end unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _tmp = match_string(">") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HtmlTag unless _tmp return _tmp end # Eof = !. def _Eof _save = self.pos _tmp = get_byte _tmp = _tmp ? nil : true self.pos = _save set_failed_rule :_Eof unless _tmp return _tmp end # Nonspacechar = !@Spacechar !@Newline . def _Nonspacechar _save = self.pos while true # sequence _save1 = self.pos _tmp = _Spacechar() _tmp = _tmp ? nil : true self.pos = _save1 unless _tmp self.pos = _save break end _save2 = self.pos _tmp = _Newline() _tmp = _tmp ? nil : true self.pos = _save2 unless _tmp self.pos = _save break end _tmp = get_byte unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Nonspacechar unless _tmp return _tmp end # Sp = @Spacechar* def _Sp while true _tmp = _Spacechar() break unless _tmp end _tmp = true set_failed_rule :_Sp unless _tmp return _tmp end # Spnl = @Sp (@Newline @Sp)? def _Spnl _save = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save break end _save1 = self.pos _save2 = self.pos while true # sequence _tmp = _Newline() unless _tmp self.pos = _save2 break end _tmp = _Sp() unless _tmp self.pos = _save2 end break end # end sequence unless _tmp _tmp = true self.pos = _save1 end unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Spnl unless _tmp return _tmp end # SpecialChar = (/[~*_`&\[\]()= 48 and _tmp <= 57 self.pos = _save _tmp = nil end end set_failed_rule :_Digit unless _tmp return _tmp end # Alphanumeric = %literals.Alphanumeric def _Alphanumeric _tmp = @_grammar_literals.external_invoke(self, :_Alphanumeric) set_failed_rule :_Alphanumeric unless _tmp return _tmp end # AlphanumericAscii = %literals.AlphanumericAscii def _AlphanumericAscii _tmp = @_grammar_literals.external_invoke(self, :_AlphanumericAscii) set_failed_rule :_AlphanumericAscii unless _tmp return _tmp end # BOM = %literals.BOM def _BOM _tmp = @_grammar_literals.external_invoke(self, :_BOM) set_failed_rule :_BOM unless _tmp return _tmp end # Newline = %literals.Newline def _Newline _tmp = @_grammar_literals.external_invoke(self, :_Newline) set_failed_rule :_Newline unless _tmp return _tmp end # Spacechar = %literals.Spacechar def _Spacechar _tmp = @_grammar_literals.external_invoke(self, :_Spacechar) set_failed_rule :_Spacechar unless _tmp return _tmp end # HexEntity = /&#x/i < /[0-9a-fA-F]+/ > ";" { [text.to_i(16)].pack 'U' } def _HexEntity _save = self.pos while true # sequence _tmp = scan(/\G(?i-mx:&#x)/) unless _tmp self.pos = _save break end _text_start = self.pos _tmp = scan(/\G(?-mix:[0-9a-fA-F]+)/) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = match_string(";") unless _tmp self.pos = _save break end @result = begin; [text.to_i(16)].pack 'U' ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_HexEntity unless _tmp return _tmp end # DecEntity = "&#" < /[0-9]+/ > ";" { [text.to_i].pack 'U' } def _DecEntity _save = self.pos while true # sequence _tmp = match_string("&#") unless _tmp self.pos = _save break end _text_start = self.pos _tmp = scan(/\G(?-mix:[0-9]+)/) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = match_string(";") unless _tmp self.pos = _save break end @result = begin; [text.to_i].pack 'U' ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_DecEntity unless _tmp return _tmp end # CharEntity = "&" < /[A-Za-z0-9]+/ > ";" { if entity = HTML_ENTITIES[text] then entity.pack 'U*' else "&#{text};" end } def _CharEntity _save = self.pos while true # sequence _tmp = match_string("&") unless _tmp self.pos = _save break end _text_start = self.pos _tmp = scan(/\G(?-mix:[A-Za-z0-9]+)/) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = match_string(";") unless _tmp self.pos = _save break end @result = begin; if entity = HTML_ENTITIES[text] then entity.pack 'U*' else "&#{text};" end ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_CharEntity unless _tmp return _tmp end # NonindentSpace = / {0,3}/ def _NonindentSpace _tmp = scan(/\G(?-mix: {0,3})/) set_failed_rule :_NonindentSpace unless _tmp return _tmp end # Indent = /\t| / def _Indent _tmp = scan(/\G(?-mix:\t| )/) set_failed_rule :_Indent unless _tmp return _tmp end # IndentedLine = Indent Line def _IndentedLine _save = self.pos while true # sequence _tmp = apply(:_Indent) unless _tmp self.pos = _save break end _tmp = apply(:_Line) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_IndentedLine unless _tmp return _tmp end # OptionallyIndentedLine = Indent? Line def _OptionallyIndentedLine _save = self.pos while true # sequence _save1 = self.pos _tmp = apply(:_Indent) unless _tmp _tmp = true self.pos = _save1 end unless _tmp self.pos = _save break end _tmp = apply(:_Line) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_OptionallyIndentedLine unless _tmp return _tmp end # StartList = &. { [] } def _StartList _save = self.pos while true # sequence _save1 = self.pos _tmp = get_byte self.pos = _save1 unless _tmp self.pos = _save break end @result = begin; [] ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_StartList unless _tmp return _tmp end # Line = @RawLine:a { a } def _Line _save = self.pos while true # sequence _tmp = _RawLine() a = @result unless _tmp self.pos = _save break end @result = begin; a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Line unless _tmp return _tmp end # RawLine = (< /[^\r\n]*/ @Newline > | < .+ > @Eof) { text } def _RawLine _save = self.pos while true # sequence _save1 = self.pos while true # choice _text_start = self.pos _save2 = self.pos while true # sequence _tmp = scan(/\G(?-mix:[^\r\n]*)/) unless _tmp self.pos = _save2 break end _tmp = _Newline() unless _tmp self.pos = _save2 end break end # end sequence if _tmp text = get_text(_text_start) end break if _tmp self.pos = _save1 _save3 = self.pos while true # sequence _text_start = self.pos _save4 = self.pos _tmp = get_byte if _tmp while true _tmp = get_byte break unless _tmp end _tmp = true else self.pos = _save4 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save3 break end _tmp = _Eof() unless _tmp self.pos = _save3 end break end # end sequence break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_RawLine unless _tmp return _tmp end # SkipBlock = (HtmlBlock | (!"#" !SetextBottom1 !SetextBottom2 !@BlankLine @RawLine)+ @BlankLine* | @BlankLine+ | @RawLine) def _SkipBlock _save = self.pos while true # choice _tmp = apply(:_HtmlBlock) break if _tmp self.pos = _save _save1 = self.pos while true # sequence _save2 = self.pos _save3 = self.pos while true # sequence _save4 = self.pos _tmp = match_string("#") _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _save5 = self.pos _tmp = apply(:_SetextBottom1) _tmp = _tmp ? nil : true self.pos = _save5 unless _tmp self.pos = _save3 break end _save6 = self.pos _tmp = apply(:_SetextBottom2) _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save3 break end _save7 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save7 unless _tmp self.pos = _save3 break end _tmp = _RawLine() unless _tmp self.pos = _save3 end break end # end sequence if _tmp while true _save8 = self.pos while true # sequence _save9 = self.pos _tmp = match_string("#") _tmp = _tmp ? nil : true self.pos = _save9 unless _tmp self.pos = _save8 break end _save10 = self.pos _tmp = apply(:_SetextBottom1) _tmp = _tmp ? nil : true self.pos = _save10 unless _tmp self.pos = _save8 break end _save11 = self.pos _tmp = apply(:_SetextBottom2) _tmp = _tmp ? nil : true self.pos = _save11 unless _tmp self.pos = _save8 break end _save12 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save12 unless _tmp self.pos = _save8 break end _tmp = _RawLine() unless _tmp self.pos = _save8 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save1 break end while true _tmp = _BlankLine() break unless _tmp end _tmp = true unless _tmp self.pos = _save1 end break end # end sequence break if _tmp self.pos = _save _save14 = self.pos _tmp = _BlankLine() if _tmp while true _tmp = _BlankLine() break unless _tmp end _tmp = true else self.pos = _save14 end break if _tmp self.pos = _save _tmp = _RawLine() break if _tmp self.pos = _save break end # end choice set_failed_rule :_SkipBlock unless _tmp return _tmp end # ExtendedSpecialChar = &{ notes? } "^" def _ExtendedSpecialChar _save = self.pos while true # sequence _save1 = self.pos _tmp = begin; notes? ; end self.pos = _save1 unless _tmp self.pos = _save break end _tmp = match_string("^") unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_ExtendedSpecialChar unless _tmp return _tmp end # NoteReference = &{ notes? } RawNoteReference:ref { note_for ref } def _NoteReference _save = self.pos while true # sequence _save1 = self.pos _tmp = begin; notes? ; end self.pos = _save1 unless _tmp self.pos = _save break end _tmp = apply(:_RawNoteReference) ref = @result unless _tmp self.pos = _save break end @result = begin; note_for ref ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_NoteReference unless _tmp return _tmp end # RawNoteReference = "[^" < (!@Newline !"]" .)+ > "]" { text } def _RawNoteReference _save = self.pos while true # sequence _tmp = match_string("[^") unless _tmp self.pos = _save break end _text_start = self.pos _save1 = self.pos _save2 = self.pos while true # sequence _save3 = self.pos _tmp = _Newline() _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _save4 = self.pos _tmp = match_string("]") _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save2 break end _tmp = get_byte unless _tmp self.pos = _save2 end break end # end sequence if _tmp while true _save5 = self.pos while true # sequence _save6 = self.pos _tmp = _Newline() _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save5 break end _save7 = self.pos _tmp = match_string("]") _tmp = _tmp ? nil : true self.pos = _save7 unless _tmp self.pos = _save5 break end _tmp = get_byte unless _tmp self.pos = _save5 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save1 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = match_string("]") unless _tmp self.pos = _save break end @result = begin; text ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_RawNoteReference unless _tmp return _tmp end # Note = &{ notes? } @NonindentSpace RawNoteReference:ref ":" @Sp @StartList:a RawNoteBlock:i { a.concat i } (&Indent RawNoteBlock:i { a.concat i })* { @footnotes[ref] = paragraph a nil } def _Note _save = self.pos while true # sequence _save1 = self.pos _tmp = begin; notes? ; end self.pos = _save1 unless _tmp self.pos = _save break end _tmp = _NonindentSpace() unless _tmp self.pos = _save break end _tmp = apply(:_RawNoteReference) ref = @result unless _tmp self.pos = _save break end _tmp = match_string(":") unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _tmp = apply(:_RawNoteBlock) i = @result unless _tmp self.pos = _save break end @result = begin; a.concat i ; end _tmp = true unless _tmp self.pos = _save break end while true _save3 = self.pos while true # sequence _save4 = self.pos _tmp = apply(:_Indent) self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = apply(:_RawNoteBlock) i = @result unless _tmp self.pos = _save3 break end @result = begin; a.concat i ; end _tmp = true unless _tmp self.pos = _save3 end break end # end sequence break unless _tmp end _tmp = true unless _tmp self.pos = _save break end @result = begin; @footnotes[ref] = paragraph a nil ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Note unless _tmp return _tmp end # InlineNote = &{ notes? } "^[" @StartList:a (!"]" Inline:l { a << l })+ "]" { ref = [:inline, @note_order.length] @footnotes[ref] = paragraph a note_for ref } def _InlineNote _save = self.pos while true # sequence _save1 = self.pos _tmp = begin; notes? ; end self.pos = _save1 unless _tmp self.pos = _save break end _tmp = match_string("^[") unless _tmp self.pos = _save break end _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # sequence _save4 = self.pos _tmp = match_string("]") _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save3 break end _tmp = apply(:_Inline) l = @result unless _tmp self.pos = _save3 break end @result = begin; a << l ; end _tmp = true unless _tmp self.pos = _save3 end break end # end sequence if _tmp while true _save5 = self.pos while true # sequence _save6 = self.pos _tmp = match_string("]") _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save5 break end _tmp = apply(:_Inline) l = @result unless _tmp self.pos = _save5 break end @result = begin; a << l ; end _tmp = true unless _tmp self.pos = _save5 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save2 end unless _tmp self.pos = _save break end _tmp = match_string("]") unless _tmp self.pos = _save break end @result = begin; ref = [:inline, @note_order.length] @footnotes[ref] = paragraph a note_for ref ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_InlineNote unless _tmp return _tmp end # Notes = (Note | SkipBlock)* def _Notes while true _save1 = self.pos while true # choice _tmp = apply(:_Note) break if _tmp self.pos = _save1 _tmp = apply(:_SkipBlock) break if _tmp self.pos = _save1 break end # end choice break unless _tmp end _tmp = true set_failed_rule :_Notes unless _tmp return _tmp end # RawNoteBlock = @StartList:a (!@BlankLine !RawNoteReference OptionallyIndentedLine:l { a << l })+ < @BlankLine* > { a << text } { a } def _RawNoteBlock _save = self.pos while true # sequence _tmp = _StartList() a = @result unless _tmp self.pos = _save break end _save1 = self.pos _save2 = self.pos while true # sequence _save3 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save3 unless _tmp self.pos = _save2 break end _save4 = self.pos _tmp = apply(:_RawNoteReference) _tmp = _tmp ? nil : true self.pos = _save4 unless _tmp self.pos = _save2 break end _tmp = apply(:_OptionallyIndentedLine) l = @result unless _tmp self.pos = _save2 break end @result = begin; a << l ; end _tmp = true unless _tmp self.pos = _save2 end break end # end sequence if _tmp while true _save5 = self.pos while true # sequence _save6 = self.pos _tmp = _BlankLine() _tmp = _tmp ? nil : true self.pos = _save6 unless _tmp self.pos = _save5 break end _save7 = self.pos _tmp = apply(:_RawNoteReference) _tmp = _tmp ? nil : true self.pos = _save7 unless _tmp self.pos = _save5 break end _tmp = apply(:_OptionallyIndentedLine) l = @result unless _tmp self.pos = _save5 break end @result = begin; a << l ; end _tmp = true unless _tmp self.pos = _save5 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save1 end unless _tmp self.pos = _save break end _text_start = self.pos while true _tmp = _BlankLine() break unless _tmp end _tmp = true if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; a << text ; end _tmp = true unless _tmp self.pos = _save break end @result = begin; a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_RawNoteBlock unless _tmp return _tmp end # CodeFence = &{ github? } Ticks3 (@Sp StrChunk:format)? Spnl < ((!"`" Nonspacechar)+ | !Ticks3 /`+/ | Spacechar | @Newline)+ > Ticks3 @Sp @Newline* { verbatim = RDoc::Markup::Verbatim.new text verbatim.format = format.intern if format.instance_of?(String) verbatim } def _CodeFence _save = self.pos while true # sequence _save1 = self.pos _tmp = begin; github? ; end self.pos = _save1 unless _tmp self.pos = _save break end _tmp = apply(:_Ticks3) unless _tmp self.pos = _save break end _save2 = self.pos _save3 = self.pos while true # sequence _tmp = _Sp() unless _tmp self.pos = _save3 break end _tmp = apply(:_StrChunk) format = @result unless _tmp self.pos = _save3 end break end # end sequence unless _tmp _tmp = true self.pos = _save2 end unless _tmp self.pos = _save break end _tmp = apply(:_Spnl) unless _tmp self.pos = _save break end _text_start = self.pos _save4 = self.pos _save5 = self.pos while true # choice _save6 = self.pos _save7 = self.pos while true # sequence _save8 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save8 unless _tmp self.pos = _save7 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save7 end break end # end sequence if _tmp while true _save9 = self.pos while true # sequence _save10 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save10 unless _tmp self.pos = _save9 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save9 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save6 end break if _tmp self.pos = _save5 _save11 = self.pos while true # sequence _save12 = self.pos _tmp = apply(:_Ticks3) _tmp = _tmp ? nil : true self.pos = _save12 unless _tmp self.pos = _save11 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save11 end break end # end sequence break if _tmp self.pos = _save5 _tmp = apply(:_Spacechar) break if _tmp self.pos = _save5 _tmp = _Newline() break if _tmp self.pos = _save5 break end # end choice if _tmp while true _save13 = self.pos while true # choice _save14 = self.pos _save15 = self.pos while true # sequence _save16 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save16 unless _tmp self.pos = _save15 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save15 end break end # end sequence if _tmp while true _save17 = self.pos while true # sequence _save18 = self.pos _tmp = match_string("`") _tmp = _tmp ? nil : true self.pos = _save18 unless _tmp self.pos = _save17 break end _tmp = apply(:_Nonspacechar) unless _tmp self.pos = _save17 end break end # end sequence break unless _tmp end _tmp = true else self.pos = _save14 end break if _tmp self.pos = _save13 _save19 = self.pos while true # sequence _save20 = self.pos _tmp = apply(:_Ticks3) _tmp = _tmp ? nil : true self.pos = _save20 unless _tmp self.pos = _save19 break end _tmp = scan(/\G(?-mix:`+)/) unless _tmp self.pos = _save19 end break end # end sequence break if _tmp self.pos = _save13 _tmp = apply(:_Spacechar) break if _tmp self.pos = _save13 _tmp = _Newline() break if _tmp self.pos = _save13 break end # end choice break unless _tmp end _tmp = true else self.pos = _save4 end if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = apply(:_Ticks3) unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end while true _tmp = _Newline() break unless _tmp end _tmp = true unless _tmp self.pos = _save break end @result = begin; verbatim = RDoc::Markup::Verbatim.new text verbatim.format = format.intern if format.instance_of?(String) verbatim ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_CodeFence unless _tmp return _tmp end # Table = &{ github? } TableHead:header TableLine:line TableRow+:body { table = RDoc::Markup::Table.new(header, line, body) } def _Table _save = self.pos while true # sequence _save1 = self.pos _tmp = begin; github? ; end self.pos = _save1 unless _tmp self.pos = _save break end _tmp = apply(:_TableHead) header = @result unless _tmp self.pos = _save break end _tmp = apply(:_TableLine) line = @result unless _tmp self.pos = _save break end _save2 = self.pos _ary = [] _tmp = apply(:_TableRow) if _tmp _ary << @result while true _tmp = apply(:_TableRow) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save2 end body = @result unless _tmp self.pos = _save break end @result = begin; table = RDoc::Markup::Table.new(header, line, body) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_Table unless _tmp return _tmp end # TableHead = TableItem2+:items "|"? @Newline { items } def _TableHead _save = self.pos while true # sequence _save1 = self.pos _ary = [] _tmp = apply(:_TableItem2) if _tmp _ary << @result while true _tmp = apply(:_TableItem2) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save1 end items = @result unless _tmp self.pos = _save break end _save2 = self.pos _tmp = match_string("|") unless _tmp _tmp = true self.pos = _save2 end unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end @result = begin; items ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TableHead unless _tmp return _tmp end # TableRow = ((TableItem:item1 TableItem2*:items { [item1, *items] }):row | TableItem2+:row) "|"? @Newline { row } def _TableRow _save = self.pos while true # sequence _save1 = self.pos while true # choice _save2 = self.pos while true # sequence _tmp = apply(:_TableItem) item1 = @result unless _tmp self.pos = _save2 break end _ary = [] while true _tmp = apply(:_TableItem2) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary items = @result unless _tmp self.pos = _save2 break end @result = begin; [item1, *items] ; end _tmp = true unless _tmp self.pos = _save2 end break end # end sequence row = @result break if _tmp self.pos = _save1 _save4 = self.pos _ary = [] _tmp = apply(:_TableItem2) if _tmp _ary << @result while true _tmp = apply(:_TableItem2) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save4 end row = @result break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _save5 = self.pos _tmp = match_string("|") unless _tmp _tmp = true self.pos = _save5 end unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end @result = begin; row ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TableRow unless _tmp return _tmp end # TableItem2 = "|" TableItem def _TableItem2 _save = self.pos while true # sequence _tmp = match_string("|") unless _tmp self.pos = _save break end _tmp = apply(:_TableItem) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TableItem2 unless _tmp return _tmp end # TableItem = < /(?:\\.|[^|\n])+/ > { text.strip.gsub(/\\(.)/, '\1') } def _TableItem _save = self.pos while true # sequence _text_start = self.pos _tmp = scan(/\G(?-mix:(?:\\.|[^|\n])+)/) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end @result = begin; text.strip.gsub(/\\(.)/, '\1') ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TableItem unless _tmp return _tmp end # TableLine = ((TableAlign:align1 TableAlign2*:aligns {[align1, *aligns] }):line | TableAlign2+:line) "|"? @Newline { line } def _TableLine _save = self.pos while true # sequence _save1 = self.pos while true # choice _save2 = self.pos while true # sequence _tmp = apply(:_TableAlign) align1 = @result unless _tmp self.pos = _save2 break end _ary = [] while true _tmp = apply(:_TableAlign2) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary aligns = @result unless _tmp self.pos = _save2 break end @result = begin; [align1, *aligns] ; end _tmp = true unless _tmp self.pos = _save2 end break end # end sequence line = @result break if _tmp self.pos = _save1 _save4 = self.pos _ary = [] _tmp = apply(:_TableAlign2) if _tmp _ary << @result while true _tmp = apply(:_TableAlign2) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save4 end line = @result break if _tmp self.pos = _save1 break end # end choice unless _tmp self.pos = _save break end _save5 = self.pos _tmp = match_string("|") unless _tmp _tmp = true self.pos = _save5 end unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end @result = begin; line ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TableLine unless _tmp return _tmp end # TableAlign2 = "|" @Sp TableAlign def _TableAlign2 _save = self.pos while true # sequence _tmp = match_string("|") unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = apply(:_TableAlign) unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TableAlign2 unless _tmp return _tmp end # TableAlign = < /:?-+:?/ > @Sp { text.start_with?(":") ? (text.end_with?(":") ? :center : :left) : (text.end_with?(":") ? :right : nil) } def _TableAlign _save = self.pos while true # sequence _text_start = self.pos _tmp = scan(/\G(?-mix::?-+:?)/) if _tmp text = get_text(_text_start) end unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end @result = begin; text.start_with?(":") ? (text.end_with?(":") ? :center : :left) : (text.end_with?(":") ? :right : nil) ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_TableAlign unless _tmp return _tmp end # DefinitionList = &{ definition_lists? } DefinitionListItem+:list { RDoc::Markup::List.new :NOTE, *list.flatten } def _DefinitionList _save = self.pos while true # sequence _save1 = self.pos _tmp = begin; definition_lists? ; end self.pos = _save1 unless _tmp self.pos = _save break end _save2 = self.pos _ary = [] _tmp = apply(:_DefinitionListItem) if _tmp _ary << @result while true _tmp = apply(:_DefinitionListItem) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save2 end list = @result unless _tmp self.pos = _save break end @result = begin; RDoc::Markup::List.new :NOTE, *list.flatten ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_DefinitionList unless _tmp return _tmp end # DefinitionListItem = DefinitionListLabel+:label DefinitionListDefinition+:defns { list_items = [] list_items << RDoc::Markup::ListItem.new(label, defns.shift) list_items.concat defns.map { |defn| RDoc::Markup::ListItem.new nil, defn } unless list_items.empty? list_items } def _DefinitionListItem _save = self.pos while true # sequence _save1 = self.pos _ary = [] _tmp = apply(:_DefinitionListLabel) if _tmp _ary << @result while true _tmp = apply(:_DefinitionListLabel) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save1 end label = @result unless _tmp self.pos = _save break end _save2 = self.pos _ary = [] _tmp = apply(:_DefinitionListDefinition) if _tmp _ary << @result while true _tmp = apply(:_DefinitionListDefinition) _ary << @result if _tmp break unless _tmp end _tmp = true @result = _ary else self.pos = _save2 end defns = @result unless _tmp self.pos = _save break end @result = begin; list_items = [] list_items << RDoc::Markup::ListItem.new(label, defns.shift) list_items.concat defns.map { |defn| RDoc::Markup::ListItem.new nil, defn } unless list_items.empty? list_items ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_DefinitionListItem unless _tmp return _tmp end # DefinitionListLabel = StrChunk:label @Sp @Newline { label } def _DefinitionListLabel _save = self.pos while true # sequence _tmp = apply(:_StrChunk) label = @result unless _tmp self.pos = _save break end _tmp = _Sp() unless _tmp self.pos = _save break end _tmp = _Newline() unless _tmp self.pos = _save break end @result = begin; label ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_DefinitionListLabel unless _tmp return _tmp end # DefinitionListDefinition = @NonindentSpace ":" @Space Inlines:a @BlankLine+ { paragraph a } def _DefinitionListDefinition _save = self.pos while true # sequence _tmp = _NonindentSpace() unless _tmp self.pos = _save break end _tmp = match_string(":") unless _tmp self.pos = _save break end _tmp = _Space() unless _tmp self.pos = _save break end _tmp = apply(:_Inlines) a = @result unless _tmp self.pos = _save break end _save1 = self.pos _tmp = _BlankLine() if _tmp while true _tmp = _BlankLine() break unless _tmp end _tmp = true else self.pos = _save1 end unless _tmp self.pos = _save break end @result = begin; paragraph a ; end _tmp = true unless _tmp self.pos = _save end break end # end sequence set_failed_rule :_DefinitionListDefinition unless _tmp return _tmp end Rules = {} Rules[:_root] = rule_info("root", "Doc") Rules[:_Doc] = rule_info("Doc", "BOM? Block*:a { RDoc::Markup::Document.new(*a.compact) }") Rules[:_Block] = rule_info("Block", "@BlankLine* (BlockQuote | Verbatim | CodeFence | Table | Note | Reference | HorizontalRule | Heading | OrderedList | BulletList | DefinitionList | HtmlBlock | StyleBlock | Para | Plain)") Rules[:_Para] = rule_info("Para", "@NonindentSpace Inlines:a @BlankLine+ { paragraph a }") Rules[:_Plain] = rule_info("Plain", "Inlines:a { paragraph a }") Rules[:_AtxInline] = rule_info("AtxInline", "!@Newline !(@Sp /\#*/ @Sp @Newline) Inline") Rules[:_AtxStart] = rule_info("AtxStart", "< /\\\#{1,6}/ > { text.length }") Rules[:_AtxHeading] = rule_info("AtxHeading", "AtxStart:s @Sp AtxInline+:a (@Sp /\#*/ @Sp)? @Newline { RDoc::Markup::Heading.new(s, a.join) }") Rules[:_SetextHeading] = rule_info("SetextHeading", "(SetextHeading1 | SetextHeading2)") Rules[:_SetextBottom1] = rule_info("SetextBottom1", "/={1,}/ @Newline") Rules[:_SetextBottom2] = rule_info("SetextBottom2", "/-{1,}/ @Newline") Rules[:_SetextHeading1] = rule_info("SetextHeading1", "&(@RawLine SetextBottom1) @StartList:a (!@Endline Inline:b { a << b })+ @Sp @Newline SetextBottom1 { RDoc::Markup::Heading.new(1, a.join) }") Rules[:_SetextHeading2] = rule_info("SetextHeading2", "&(@RawLine SetextBottom2) @StartList:a (!@Endline Inline:b { a << b })+ @Sp @Newline SetextBottom2 { RDoc::Markup::Heading.new(2, a.join) }") Rules[:_Heading] = rule_info("Heading", "(SetextHeading | AtxHeading)") Rules[:_BlockQuote] = rule_info("BlockQuote", "BlockQuoteRaw:a { RDoc::Markup::BlockQuote.new(*a) }") Rules[:_BlockQuoteRaw] = rule_info("BlockQuoteRaw", "@StartList:a (\">\" \" \"? Line:l { a << l } (!\">\" !@BlankLine Line:c { a << c })* (@BlankLine:n { a << n })*)+ { inner_parse a.join }") Rules[:_NonblankIndentedLine] = rule_info("NonblankIndentedLine", "!@BlankLine IndentedLine") Rules[:_VerbatimChunk] = rule_info("VerbatimChunk", "@BlankLine*:a NonblankIndentedLine+:b { a.concat b }") Rules[:_Verbatim] = rule_info("Verbatim", "VerbatimChunk+:a { RDoc::Markup::Verbatim.new(*a.flatten) }") Rules[:_HorizontalRule] = rule_info("HorizontalRule", "@NonindentSpace (\"*\" @Sp \"*\" @Sp \"*\" (@Sp \"*\")* | \"-\" @Sp \"-\" @Sp \"-\" (@Sp \"-\")* | \"_\" @Sp \"_\" @Sp \"_\" (@Sp \"_\")*) @Sp @Newline @BlankLine+ { RDoc::Markup::Rule.new 1 }") Rules[:_Bullet] = rule_info("Bullet", "!HorizontalRule @NonindentSpace /[+*-]/ @Spacechar+") Rules[:_BulletList] = rule_info("BulletList", "&Bullet (ListTight | ListLoose):a { RDoc::Markup::List.new(:BULLET, *a) }") Rules[:_ListTight] = rule_info("ListTight", "ListItemTight+:a @BlankLine* !(Bullet | Enumerator) { a }") Rules[:_ListLoose] = rule_info("ListLoose", "@StartList:a (ListItem:b @BlankLine* { a << b })+ { a }") Rules[:_ListItem] = rule_info("ListItem", "(Bullet | Enumerator) @StartList:a ListBlock:b { a << b } (ListContinuationBlock:c { a.push(*c) })* { list_item_from a }") Rules[:_ListItemTight] = rule_info("ListItemTight", "(Bullet | Enumerator) ListBlock:a (!@BlankLine ListContinuationBlock:b { a.push(*b) })* !ListContinuationBlock { list_item_from a }") Rules[:_ListBlock] = rule_info("ListBlock", "!@BlankLine Line:a ListBlockLine*:c { [a, *c] }") Rules[:_ListContinuationBlock] = rule_info("ListContinuationBlock", "@StartList:a @BlankLine* { a << \"\\n\" } (Indent ListBlock:b { a.concat b })+ { a }") Rules[:_Enumerator] = rule_info("Enumerator", "@NonindentSpace [0-9]+ \".\" @Spacechar+") Rules[:_OrderedList] = rule_info("OrderedList", "&Enumerator (ListTight | ListLoose):a { RDoc::Markup::List.new(:NUMBER, *a) }") Rules[:_ListBlockLine] = rule_info("ListBlockLine", "!@BlankLine !(Indent? (Bullet | Enumerator)) !HorizontalRule OptionallyIndentedLine") Rules[:_HtmlOpenAnchor] = rule_info("HtmlOpenAnchor", "\"<\" Spnl (\"a\" | \"A\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlCloseAnchor] = rule_info("HtmlCloseAnchor", "\"<\" Spnl \"/\" (\"a\" | \"A\") Spnl \">\"") Rules[:_HtmlAnchor] = rule_info("HtmlAnchor", "HtmlOpenAnchor (HtmlAnchor | !HtmlCloseAnchor .)* HtmlCloseAnchor") Rules[:_HtmlBlockOpenAddress] = rule_info("HtmlBlockOpenAddress", "\"<\" Spnl (\"address\" | \"ADDRESS\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseAddress] = rule_info("HtmlBlockCloseAddress", "\"<\" Spnl \"/\" (\"address\" | \"ADDRESS\") Spnl \">\"") Rules[:_HtmlBlockAddress] = rule_info("HtmlBlockAddress", "HtmlBlockOpenAddress (HtmlBlockAddress | !HtmlBlockCloseAddress .)* HtmlBlockCloseAddress") Rules[:_HtmlBlockOpenBlockquote] = rule_info("HtmlBlockOpenBlockquote", "\"<\" Spnl (\"blockquote\" | \"BLOCKQUOTE\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseBlockquote] = rule_info("HtmlBlockCloseBlockquote", "\"<\" Spnl \"/\" (\"blockquote\" | \"BLOCKQUOTE\") Spnl \">\"") Rules[:_HtmlBlockBlockquote] = rule_info("HtmlBlockBlockquote", "HtmlBlockOpenBlockquote (HtmlBlockBlockquote | !HtmlBlockCloseBlockquote .)* HtmlBlockCloseBlockquote") Rules[:_HtmlBlockOpenCenter] = rule_info("HtmlBlockOpenCenter", "\"<\" Spnl (\"center\" | \"CENTER\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseCenter] = rule_info("HtmlBlockCloseCenter", "\"<\" Spnl \"/\" (\"center\" | \"CENTER\") Spnl \">\"") Rules[:_HtmlBlockCenter] = rule_info("HtmlBlockCenter", "HtmlBlockOpenCenter (HtmlBlockCenter | !HtmlBlockCloseCenter .)* HtmlBlockCloseCenter") Rules[:_HtmlBlockOpenDir] = rule_info("HtmlBlockOpenDir", "\"<\" Spnl (\"dir\" | \"DIR\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseDir] = rule_info("HtmlBlockCloseDir", "\"<\" Spnl \"/\" (\"dir\" | \"DIR\") Spnl \">\"") Rules[:_HtmlBlockDir] = rule_info("HtmlBlockDir", "HtmlBlockOpenDir (HtmlBlockDir | !HtmlBlockCloseDir .)* HtmlBlockCloseDir") Rules[:_HtmlBlockOpenDiv] = rule_info("HtmlBlockOpenDiv", "\"<\" Spnl (\"div\" | \"DIV\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseDiv] = rule_info("HtmlBlockCloseDiv", "\"<\" Spnl \"/\" (\"div\" | \"DIV\") Spnl \">\"") Rules[:_HtmlBlockDiv] = rule_info("HtmlBlockDiv", "HtmlBlockOpenDiv (HtmlBlockDiv | !HtmlBlockCloseDiv .)* HtmlBlockCloseDiv") Rules[:_HtmlBlockOpenDl] = rule_info("HtmlBlockOpenDl", "\"<\" Spnl (\"dl\" | \"DL\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseDl] = rule_info("HtmlBlockCloseDl", "\"<\" Spnl \"/\" (\"dl\" | \"DL\") Spnl \">\"") Rules[:_HtmlBlockDl] = rule_info("HtmlBlockDl", "HtmlBlockOpenDl (HtmlBlockDl | !HtmlBlockCloseDl .)* HtmlBlockCloseDl") Rules[:_HtmlBlockOpenFieldset] = rule_info("HtmlBlockOpenFieldset", "\"<\" Spnl (\"fieldset\" | \"FIELDSET\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseFieldset] = rule_info("HtmlBlockCloseFieldset", "\"<\" Spnl \"/\" (\"fieldset\" | \"FIELDSET\") Spnl \">\"") Rules[:_HtmlBlockFieldset] = rule_info("HtmlBlockFieldset", "HtmlBlockOpenFieldset (HtmlBlockFieldset | !HtmlBlockCloseFieldset .)* HtmlBlockCloseFieldset") Rules[:_HtmlBlockOpenForm] = rule_info("HtmlBlockOpenForm", "\"<\" Spnl (\"form\" | \"FORM\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseForm] = rule_info("HtmlBlockCloseForm", "\"<\" Spnl \"/\" (\"form\" | \"FORM\") Spnl \">\"") Rules[:_HtmlBlockForm] = rule_info("HtmlBlockForm", "HtmlBlockOpenForm (HtmlBlockForm | !HtmlBlockCloseForm .)* HtmlBlockCloseForm") Rules[:_HtmlBlockOpenH1] = rule_info("HtmlBlockOpenH1", "\"<\" Spnl (\"h1\" | \"H1\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseH1] = rule_info("HtmlBlockCloseH1", "\"<\" Spnl \"/\" (\"h1\" | \"H1\") Spnl \">\"") Rules[:_HtmlBlockH1] = rule_info("HtmlBlockH1", "HtmlBlockOpenH1 (HtmlBlockH1 | !HtmlBlockCloseH1 .)* HtmlBlockCloseH1") Rules[:_HtmlBlockOpenH2] = rule_info("HtmlBlockOpenH2", "\"<\" Spnl (\"h2\" | \"H2\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseH2] = rule_info("HtmlBlockCloseH2", "\"<\" Spnl \"/\" (\"h2\" | \"H2\") Spnl \">\"") Rules[:_HtmlBlockH2] = rule_info("HtmlBlockH2", "HtmlBlockOpenH2 (HtmlBlockH2 | !HtmlBlockCloseH2 .)* HtmlBlockCloseH2") Rules[:_HtmlBlockOpenH3] = rule_info("HtmlBlockOpenH3", "\"<\" Spnl (\"h3\" | \"H3\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseH3] = rule_info("HtmlBlockCloseH3", "\"<\" Spnl \"/\" (\"h3\" | \"H3\") Spnl \">\"") Rules[:_HtmlBlockH3] = rule_info("HtmlBlockH3", "HtmlBlockOpenH3 (HtmlBlockH3 | !HtmlBlockCloseH3 .)* HtmlBlockCloseH3") Rules[:_HtmlBlockOpenH4] = rule_info("HtmlBlockOpenH4", "\"<\" Spnl (\"h4\" | \"H4\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseH4] = rule_info("HtmlBlockCloseH4", "\"<\" Spnl \"/\" (\"h4\" | \"H4\") Spnl \">\"") Rules[:_HtmlBlockH4] = rule_info("HtmlBlockH4", "HtmlBlockOpenH4 (HtmlBlockH4 | !HtmlBlockCloseH4 .)* HtmlBlockCloseH4") Rules[:_HtmlBlockOpenH5] = rule_info("HtmlBlockOpenH5", "\"<\" Spnl (\"h5\" | \"H5\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseH5] = rule_info("HtmlBlockCloseH5", "\"<\" Spnl \"/\" (\"h5\" | \"H5\") Spnl \">\"") Rules[:_HtmlBlockH5] = rule_info("HtmlBlockH5", "HtmlBlockOpenH5 (HtmlBlockH5 | !HtmlBlockCloseH5 .)* HtmlBlockCloseH5") Rules[:_HtmlBlockOpenH6] = rule_info("HtmlBlockOpenH6", "\"<\" Spnl (\"h6\" | \"H6\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseH6] = rule_info("HtmlBlockCloseH6", "\"<\" Spnl \"/\" (\"h6\" | \"H6\") Spnl \">\"") Rules[:_HtmlBlockH6] = rule_info("HtmlBlockH6", "HtmlBlockOpenH6 (HtmlBlockH6 | !HtmlBlockCloseH6 .)* HtmlBlockCloseH6") Rules[:_HtmlBlockOpenMenu] = rule_info("HtmlBlockOpenMenu", "\"<\" Spnl (\"menu\" | \"MENU\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseMenu] = rule_info("HtmlBlockCloseMenu", "\"<\" Spnl \"/\" (\"menu\" | \"MENU\") Spnl \">\"") Rules[:_HtmlBlockMenu] = rule_info("HtmlBlockMenu", "HtmlBlockOpenMenu (HtmlBlockMenu | !HtmlBlockCloseMenu .)* HtmlBlockCloseMenu") Rules[:_HtmlBlockOpenNoframes] = rule_info("HtmlBlockOpenNoframes", "\"<\" Spnl (\"noframes\" | \"NOFRAMES\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseNoframes] = rule_info("HtmlBlockCloseNoframes", "\"<\" Spnl \"/\" (\"noframes\" | \"NOFRAMES\") Spnl \">\"") Rules[:_HtmlBlockNoframes] = rule_info("HtmlBlockNoframes", "HtmlBlockOpenNoframes (HtmlBlockNoframes | !HtmlBlockCloseNoframes .)* HtmlBlockCloseNoframes") Rules[:_HtmlBlockOpenNoscript] = rule_info("HtmlBlockOpenNoscript", "\"<\" Spnl (\"noscript\" | \"NOSCRIPT\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseNoscript] = rule_info("HtmlBlockCloseNoscript", "\"<\" Spnl \"/\" (\"noscript\" | \"NOSCRIPT\") Spnl \">\"") Rules[:_HtmlBlockNoscript] = rule_info("HtmlBlockNoscript", "HtmlBlockOpenNoscript (HtmlBlockNoscript | !HtmlBlockCloseNoscript .)* HtmlBlockCloseNoscript") Rules[:_HtmlBlockOpenOl] = rule_info("HtmlBlockOpenOl", "\"<\" Spnl (\"ol\" | \"OL\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseOl] = rule_info("HtmlBlockCloseOl", "\"<\" Spnl \"/\" (\"ol\" | \"OL\") Spnl \">\"") Rules[:_HtmlBlockOl] = rule_info("HtmlBlockOl", "HtmlBlockOpenOl (HtmlBlockOl | !HtmlBlockCloseOl .)* HtmlBlockCloseOl") Rules[:_HtmlBlockOpenP] = rule_info("HtmlBlockOpenP", "\"<\" Spnl (\"p\" | \"P\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseP] = rule_info("HtmlBlockCloseP", "\"<\" Spnl \"/\" (\"p\" | \"P\") Spnl \">\"") Rules[:_HtmlBlockP] = rule_info("HtmlBlockP", "HtmlBlockOpenP (HtmlBlockP | !HtmlBlockCloseP .)* HtmlBlockCloseP") Rules[:_HtmlBlockOpenPre] = rule_info("HtmlBlockOpenPre", "\"<\" Spnl (\"pre\" | \"PRE\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockClosePre] = rule_info("HtmlBlockClosePre", "\"<\" Spnl \"/\" (\"pre\" | \"PRE\") Spnl \">\"") Rules[:_HtmlBlockPre] = rule_info("HtmlBlockPre", "HtmlBlockOpenPre (HtmlBlockPre | !HtmlBlockClosePre .)* HtmlBlockClosePre") Rules[:_HtmlBlockOpenTable] = rule_info("HtmlBlockOpenTable", "\"<\" Spnl (\"table\" | \"TABLE\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseTable] = rule_info("HtmlBlockCloseTable", "\"<\" Spnl \"/\" (\"table\" | \"TABLE\") Spnl \">\"") Rules[:_HtmlBlockTable] = rule_info("HtmlBlockTable", "HtmlBlockOpenTable (HtmlBlockTable | !HtmlBlockCloseTable .)* HtmlBlockCloseTable") Rules[:_HtmlBlockOpenUl] = rule_info("HtmlBlockOpenUl", "\"<\" Spnl (\"ul\" | \"UL\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseUl] = rule_info("HtmlBlockCloseUl", "\"<\" Spnl \"/\" (\"ul\" | \"UL\") Spnl \">\"") Rules[:_HtmlBlockUl] = rule_info("HtmlBlockUl", "HtmlBlockOpenUl (HtmlBlockUl | !HtmlBlockCloseUl .)* HtmlBlockCloseUl") Rules[:_HtmlBlockOpenDd] = rule_info("HtmlBlockOpenDd", "\"<\" Spnl (\"dd\" | \"DD\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseDd] = rule_info("HtmlBlockCloseDd", "\"<\" Spnl \"/\" (\"dd\" | \"DD\") Spnl \">\"") Rules[:_HtmlBlockDd] = rule_info("HtmlBlockDd", "HtmlBlockOpenDd (HtmlBlockDd | !HtmlBlockCloseDd .)* HtmlBlockCloseDd") Rules[:_HtmlBlockOpenDt] = rule_info("HtmlBlockOpenDt", "\"<\" Spnl (\"dt\" | \"DT\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseDt] = rule_info("HtmlBlockCloseDt", "\"<\" Spnl \"/\" (\"dt\" | \"DT\") Spnl \">\"") Rules[:_HtmlBlockDt] = rule_info("HtmlBlockDt", "HtmlBlockOpenDt (HtmlBlockDt | !HtmlBlockCloseDt .)* HtmlBlockCloseDt") Rules[:_HtmlBlockOpenFrameset] = rule_info("HtmlBlockOpenFrameset", "\"<\" Spnl (\"frameset\" | \"FRAMESET\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseFrameset] = rule_info("HtmlBlockCloseFrameset", "\"<\" Spnl \"/\" (\"frameset\" | \"FRAMESET\") Spnl \">\"") Rules[:_HtmlBlockFrameset] = rule_info("HtmlBlockFrameset", "HtmlBlockOpenFrameset (HtmlBlockFrameset | !HtmlBlockCloseFrameset .)* HtmlBlockCloseFrameset") Rules[:_HtmlBlockOpenLi] = rule_info("HtmlBlockOpenLi", "\"<\" Spnl (\"li\" | \"LI\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseLi] = rule_info("HtmlBlockCloseLi", "\"<\" Spnl \"/\" (\"li\" | \"LI\") Spnl \">\"") Rules[:_HtmlBlockLi] = rule_info("HtmlBlockLi", "HtmlBlockOpenLi (HtmlBlockLi | !HtmlBlockCloseLi .)* HtmlBlockCloseLi") Rules[:_HtmlBlockOpenTbody] = rule_info("HtmlBlockOpenTbody", "\"<\" Spnl (\"tbody\" | \"TBODY\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseTbody] = rule_info("HtmlBlockCloseTbody", "\"<\" Spnl \"/\" (\"tbody\" | \"TBODY\") Spnl \">\"") Rules[:_HtmlBlockTbody] = rule_info("HtmlBlockTbody", "HtmlBlockOpenTbody (HtmlBlockTbody | !HtmlBlockCloseTbody .)* HtmlBlockCloseTbody") Rules[:_HtmlBlockOpenTd] = rule_info("HtmlBlockOpenTd", "\"<\" Spnl (\"td\" | \"TD\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseTd] = rule_info("HtmlBlockCloseTd", "\"<\" Spnl \"/\" (\"td\" | \"TD\") Spnl \">\"") Rules[:_HtmlBlockTd] = rule_info("HtmlBlockTd", "HtmlBlockOpenTd (HtmlBlockTd | !HtmlBlockCloseTd .)* HtmlBlockCloseTd") Rules[:_HtmlBlockOpenTfoot] = rule_info("HtmlBlockOpenTfoot", "\"<\" Spnl (\"tfoot\" | \"TFOOT\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseTfoot] = rule_info("HtmlBlockCloseTfoot", "\"<\" Spnl \"/\" (\"tfoot\" | \"TFOOT\") Spnl \">\"") Rules[:_HtmlBlockTfoot] = rule_info("HtmlBlockTfoot", "HtmlBlockOpenTfoot (HtmlBlockTfoot | !HtmlBlockCloseTfoot .)* HtmlBlockCloseTfoot") Rules[:_HtmlBlockOpenTh] = rule_info("HtmlBlockOpenTh", "\"<\" Spnl (\"th\" | \"TH\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseTh] = rule_info("HtmlBlockCloseTh", "\"<\" Spnl \"/\" (\"th\" | \"TH\") Spnl \">\"") Rules[:_HtmlBlockTh] = rule_info("HtmlBlockTh", "HtmlBlockOpenTh (HtmlBlockTh | !HtmlBlockCloseTh .)* HtmlBlockCloseTh") Rules[:_HtmlBlockOpenThead] = rule_info("HtmlBlockOpenThead", "\"<\" Spnl (\"thead\" | \"THEAD\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseThead] = rule_info("HtmlBlockCloseThead", "\"<\" Spnl \"/\" (\"thead\" | \"THEAD\") Spnl \">\"") Rules[:_HtmlBlockThead] = rule_info("HtmlBlockThead", "HtmlBlockOpenThead (HtmlBlockThead | !HtmlBlockCloseThead .)* HtmlBlockCloseThead") Rules[:_HtmlBlockOpenTr] = rule_info("HtmlBlockOpenTr", "\"<\" Spnl (\"tr\" | \"TR\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseTr] = rule_info("HtmlBlockCloseTr", "\"<\" Spnl \"/\" (\"tr\" | \"TR\") Spnl \">\"") Rules[:_HtmlBlockTr] = rule_info("HtmlBlockTr", "HtmlBlockOpenTr (HtmlBlockTr | !HtmlBlockCloseTr .)* HtmlBlockCloseTr") Rules[:_HtmlBlockOpenScript] = rule_info("HtmlBlockOpenScript", "\"<\" Spnl (\"script\" | \"SCRIPT\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseScript] = rule_info("HtmlBlockCloseScript", "\"<\" Spnl \"/\" (\"script\" | \"SCRIPT\") Spnl \">\"") Rules[:_HtmlBlockScript] = rule_info("HtmlBlockScript", "HtmlBlockOpenScript (!HtmlBlockCloseScript .)* HtmlBlockCloseScript") Rules[:_HtmlBlockOpenHead] = rule_info("HtmlBlockOpenHead", "\"<\" Spnl (\"head\" | \"HEAD\") Spnl HtmlAttribute* \">\"") Rules[:_HtmlBlockCloseHead] = rule_info("HtmlBlockCloseHead", "\"<\" Spnl \"/\" (\"head\" | \"HEAD\") Spnl \">\"") Rules[:_HtmlBlockHead] = rule_info("HtmlBlockHead", "HtmlBlockOpenHead (!HtmlBlockCloseHead .)* HtmlBlockCloseHead") Rules[:_HtmlBlockInTags] = rule_info("HtmlBlockInTags", "(HtmlAnchor | HtmlBlockAddress | HtmlBlockBlockquote | HtmlBlockCenter | HtmlBlockDir | HtmlBlockDiv | HtmlBlockDl | HtmlBlockFieldset | HtmlBlockForm | HtmlBlockH1 | HtmlBlockH2 | HtmlBlockH3 | HtmlBlockH4 | HtmlBlockH5 | HtmlBlockH6 | HtmlBlockMenu | HtmlBlockNoframes | HtmlBlockNoscript | HtmlBlockOl | HtmlBlockP | HtmlBlockPre | HtmlBlockTable | HtmlBlockUl | HtmlBlockDd | HtmlBlockDt | HtmlBlockFrameset | HtmlBlockLi | HtmlBlockTbody | HtmlBlockTd | HtmlBlockTfoot | HtmlBlockTh | HtmlBlockThead | HtmlBlockTr | HtmlBlockScript | HtmlBlockHead)") Rules[:_HtmlBlock] = rule_info("HtmlBlock", "< (HtmlBlockInTags | HtmlComment | HtmlBlockSelfClosing | HtmlUnclosed) > @BlankLine+ { if html? then RDoc::Markup::Raw.new text end }") Rules[:_HtmlUnclosed] = rule_info("HtmlUnclosed", "\"<\" Spnl HtmlUnclosedType Spnl HtmlAttribute* Spnl \">\"") Rules[:_HtmlUnclosedType] = rule_info("HtmlUnclosedType", "(\"HR\" | \"hr\")") Rules[:_HtmlBlockSelfClosing] = rule_info("HtmlBlockSelfClosing", "\"<\" Spnl HtmlBlockType Spnl HtmlAttribute* \"/\" Spnl \">\"") Rules[:_HtmlBlockType] = rule_info("HtmlBlockType", "(\"ADDRESS\" | \"BLOCKQUOTE\" | \"CENTER\" | \"DD\" | \"DIR\" | \"DIV\" | \"DL\" | \"DT\" | \"FIELDSET\" | \"FORM\" | \"FRAMESET\" | \"H1\" | \"H2\" | \"H3\" | \"H4\" | \"H5\" | \"H6\" | \"HR\" | \"ISINDEX\" | \"LI\" | \"MENU\" | \"NOFRAMES\" | \"NOSCRIPT\" | \"OL\" | \"P\" | \"PRE\" | \"SCRIPT\" | \"TABLE\" | \"TBODY\" | \"TD\" | \"TFOOT\" | \"TH\" | \"THEAD\" | \"TR\" | \"UL\" | \"address\" | \"blockquote\" | \"center\" | \"dd\" | \"dir\" | \"div\" | \"dl\" | \"dt\" | \"fieldset\" | \"form\" | \"frameset\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"hr\" | \"isindex\" | \"li\" | \"menu\" | \"noframes\" | \"noscript\" | \"ol\" | \"p\" | \"pre\" | \"script\" | \"table\" | \"tbody\" | \"td\" | \"tfoot\" | \"th\" | \"thead\" | \"tr\" | \"ul\")") Rules[:_StyleOpen] = rule_info("StyleOpen", "\"<\" Spnl (\"style\" | \"STYLE\") Spnl HtmlAttribute* \">\"") Rules[:_StyleClose] = rule_info("StyleClose", "\"<\" Spnl \"/\" (\"style\" | \"STYLE\") Spnl \">\"") Rules[:_InStyleTags] = rule_info("InStyleTags", "StyleOpen (!StyleClose .)* StyleClose") Rules[:_StyleBlock] = rule_info("StyleBlock", "< InStyleTags > @BlankLine* { if css? then RDoc::Markup::Raw.new text end }") Rules[:_Inlines] = rule_info("Inlines", "(!@Endline Inline:i { i } | @Endline:c !(&{ github? } Ticks3 /[^`\\n]*$/) &Inline { c })+:chunks @Endline? { chunks }") Rules[:_Inline] = rule_info("Inline", "(Str | @Endline | UlOrStarLine | @Space | Strong | Emph | Strike | Image | Link | NoteReference | InlineNote | Code | RawHtml | Entity | EscapedChar | Symbol)") Rules[:_Space] = rule_info("Space", "@Spacechar+ { \" \" }") Rules[:_Str] = rule_info("Str", "@StartList:a < @NormalChar+ > { a = text } (StrChunk:c { a << c })* { a }") Rules[:_StrChunk] = rule_info("StrChunk", "< (@NormalChar | /_+/ &Alphanumeric)+ > { text }") Rules[:_EscapedChar] = rule_info("EscapedChar", "\"\\\\\" !@Newline < /[:\\\\`|*_{}\\[\\]()\#+.!><-]/ > { text }") Rules[:_Entity] = rule_info("Entity", "(HexEntity | DecEntity | CharEntity):a { a }") Rules[:_Endline] = rule_info("Endline", "(@LineBreak | @TerminalEndline | @NormalEndline)") Rules[:_NormalEndline] = rule_info("NormalEndline", "@Sp @Newline !@BlankLine !\">\" !AtxStart !(Line /={1,}|-{1,}/ @Newline) { \"\\n\" }") Rules[:_TerminalEndline] = rule_info("TerminalEndline", "@Sp @Newline @Eof") Rules[:_LineBreak] = rule_info("LineBreak", "\" \" @NormalEndline { RDoc::Markup::HardBreak.new }") Rules[:_Symbol] = rule_info("Symbol", "< @SpecialChar > { text }") Rules[:_UlOrStarLine] = rule_info("UlOrStarLine", "(UlLine | StarLine):a { a }") Rules[:_StarLine] = rule_info("StarLine", "(< /\\*{4,}/ > { text } | < @Spacechar /\\*+/ &@Spacechar > { text })") Rules[:_UlLine] = rule_info("UlLine", "(< /_{4,}/ > { text } | < @Spacechar /_+/ &@Spacechar > { text })") Rules[:_Emph] = rule_info("Emph", "(EmphStar | EmphUl)") Rules[:_Whitespace] = rule_info("Whitespace", "(@Spacechar | @Newline)") Rules[:_EmphStar] = rule_info("EmphStar", "\"*\" !@Whitespace @StartList:a (!\"*\" Inline:b { a << b } | StrongStar:b { a << b })+ \"*\" { emphasis a.join }") Rules[:_EmphUl] = rule_info("EmphUl", "\"_\" !@Whitespace @StartList:a (!\"_\" Inline:b { a << b } | StrongUl:b { a << b })+ \"_\" { emphasis a.join }") Rules[:_Strong] = rule_info("Strong", "(StrongStar | StrongUl)") Rules[:_StrongStar] = rule_info("StrongStar", "\"**\" !@Whitespace @StartList:a (!\"**\" Inline:b { a << b })+ \"**\" { strong a.join }") Rules[:_StrongUl] = rule_info("StrongUl", "\"__\" !@Whitespace @StartList:a (!\"__\" Inline:b { a << b })+ \"__\" { strong a.join }") Rules[:_Strike] = rule_info("Strike", "&{ strike? } \"~~\" !@Whitespace @StartList:a (!\"~~\" Inline:b { a << b })+ \"~~\" { strike a.join }") Rules[:_Image] = rule_info("Image", "\"!\" (ExplicitLink | ReferenceLink):a { \"rdoc-image:\#{a[/\\[(.*)\\]/, 1]}\" }") Rules[:_Link] = rule_info("Link", "(ExplicitLink | ReferenceLink | AutoLink)") Rules[:_ReferenceLink] = rule_info("ReferenceLink", "(ReferenceLinkDouble | ReferenceLinkSingle)") Rules[:_ReferenceLinkDouble] = rule_info("ReferenceLinkDouble", "Label:content < Spnl > !\"[]\" Label:label { link_to content, label, text }") Rules[:_ReferenceLinkSingle] = rule_info("ReferenceLinkSingle", "Label:content < (Spnl \"[]\")? > { link_to content, content, text }") Rules[:_ExplicitLink] = rule_info("ExplicitLink", "Label:l \"(\" @Sp Source:s Spnl Title @Sp \")\" { \"{\#{l}}[\#{s}]\" }") Rules[:_Source] = rule_info("Source", "(\"<\" < SourceContents > \">\" | < SourceContents >) { text }") Rules[:_SourceContents] = rule_info("SourceContents", "((!\"(\" !\")\" !\">\" Nonspacechar)+ | \"(\" SourceContents \")\")*") Rules[:_Title] = rule_info("Title", "(TitleSingle | TitleDouble | \"\"):a { a }") Rules[:_TitleSingle] = rule_info("TitleSingle", "\"'\" (!(\"'\" @Sp (\")\" | @Newline)) .)* \"'\"") Rules[:_TitleDouble] = rule_info("TitleDouble", "\"\\\"\" (!(\"\\\"\" @Sp (\")\" | @Newline)) .)* \"\\\"\"") Rules[:_AutoLink] = rule_info("AutoLink", "(AutoLinkUrl | AutoLinkEmail)") Rules[:_AutoLinkUrl] = rule_info("AutoLinkUrl", "\"<\" < /[A-Za-z]+/ \"://\" (!@Newline !\">\" .)+ > \">\" { text }") Rules[:_AutoLinkEmail] = rule_info("AutoLinkEmail", "\"<\" \"mailto:\"? < /[\\w+.\\/!%~$-]+/i \"@\" (!@Newline !\">\" .)+ > \">\" { \"mailto:\#{text}\" }") Rules[:_Reference] = rule_info("Reference", "@NonindentSpace !\"[]\" Label:label \":\" Spnl RefSrc:link RefTitle @BlankLine+ { \# TODO use title reference label, link nil }") Rules[:_Label] = rule_info("Label", "\"[\" (!\"^\" &{ notes? } | &. &{ !notes? }) @StartList:a (!\"]\" Inline:l { a << l })* \"]\" { a.join.gsub(/\\s+/, ' ') }") Rules[:_RefSrc] = rule_info("RefSrc", "< Nonspacechar+ > { text }") Rules[:_RefTitle] = rule_info("RefTitle", "(RefTitleSingle | RefTitleDouble | RefTitleParens | EmptyTitle)") Rules[:_EmptyTitle] = rule_info("EmptyTitle", "\"\"") Rules[:_RefTitleSingle] = rule_info("RefTitleSingle", "Spnl \"'\" < (!(\"'\" @Sp @Newline | @Newline) .)* > \"'\" { text }") Rules[:_RefTitleDouble] = rule_info("RefTitleDouble", "Spnl \"\\\"\" < (!(\"\\\"\" @Sp @Newline | @Newline) .)* > \"\\\"\" { text }") Rules[:_RefTitleParens] = rule_info("RefTitleParens", "Spnl \"(\" < (!(\")\" @Sp @Newline | @Newline) .)* > \")\" { text }") Rules[:_References] = rule_info("References", "(Reference | SkipBlock)*") Rules[:_Ticks1] = rule_info("Ticks1", "\"`\" !\"`\"") Rules[:_Ticks2] = rule_info("Ticks2", "\"``\" !\"`\"") Rules[:_Ticks3] = rule_info("Ticks3", "\"```\" !\"`\"") Rules[:_Ticks4] = rule_info("Ticks4", "\"````\" !\"`\"") Rules[:_Ticks5] = rule_info("Ticks5", "\"`````\" !\"`\"") Rules[:_Code] = rule_info("Code", "(Ticks1 @Sp < ((!\"`\" Nonspacechar)+ | !Ticks1 /`+/ | !(@Sp Ticks1) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks1 | Ticks2 @Sp < ((!\"`\" Nonspacechar)+ | !Ticks2 /`+/ | !(@Sp Ticks2) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks2 | Ticks3 @Sp < ((!\"`\" Nonspacechar)+ | !Ticks3 /`+/ | !(@Sp Ticks3) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks3 | Ticks4 @Sp < ((!\"`\" Nonspacechar)+ | !Ticks4 /`+/ | !(@Sp Ticks4) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks4 | Ticks5 @Sp < ((!\"`\" Nonspacechar)+ | !Ticks5 /`+/ | !(@Sp Ticks5) (@Spacechar | @Newline !@BlankLine))+ > @Sp Ticks5) { \"\#{text}\" }") Rules[:_RawHtml] = rule_info("RawHtml", "< (HtmlComment | HtmlBlockScript | HtmlTag) > { if html? then text else '' end }") Rules[:_BlankLine] = rule_info("BlankLine", "@Sp @Newline { \"\\n\" }") Rules[:_Quoted] = rule_info("Quoted", "(\"\\\"\" (!\"\\\"\" .)* \"\\\"\" | \"'\" (!\"'\" .)* \"'\")") Rules[:_HtmlAttribute] = rule_info("HtmlAttribute", "(AlphanumericAscii | \"-\")+ Spnl (\"=\" Spnl (Quoted | (!\">\" Nonspacechar)+))? Spnl") Rules[:_HtmlComment] = rule_info("HtmlComment", "\"\" .)* \"-->\"") Rules[:_HtmlTag] = rule_info("HtmlTag", "\"<\" Spnl \"/\"? AlphanumericAscii+ Spnl HtmlAttribute* \"/\"? Spnl \">\"") Rules[:_Eof] = rule_info("Eof", "!.") Rules[:_Nonspacechar] = rule_info("Nonspacechar", "!@Spacechar !@Newline .") Rules[:_Sp] = rule_info("Sp", "@Spacechar*") Rules[:_Spnl] = rule_info("Spnl", "@Sp (@Newline @Sp)?") Rules[:_SpecialChar] = rule_info("SpecialChar", "(/[~*_`&\\[\\]() \";\" { [text.to_i(16)].pack 'U' }") Rules[:_DecEntity] = rule_info("DecEntity", "\"&\#\" < /[0-9]+/ > \";\" { [text.to_i].pack 'U' }") Rules[:_CharEntity] = rule_info("CharEntity", "\"&\" < /[A-Za-z0-9]+/ > \";\" { if entity = HTML_ENTITIES[text] then entity.pack 'U*' else \"&\#{text};\" end }") Rules[:_NonindentSpace] = rule_info("NonindentSpace", "/ {0,3}/") Rules[:_Indent] = rule_info("Indent", "/\\t| /") Rules[:_IndentedLine] = rule_info("IndentedLine", "Indent Line") Rules[:_OptionallyIndentedLine] = rule_info("OptionallyIndentedLine", "Indent? Line") Rules[:_StartList] = rule_info("StartList", "&. { [] }") Rules[:_Line] = rule_info("Line", "@RawLine:a { a }") Rules[:_RawLine] = rule_info("RawLine", "(< /[^\\r\\n]*/ @Newline > | < .+ > @Eof) { text }") Rules[:_SkipBlock] = rule_info("SkipBlock", "(HtmlBlock | (!\"\#\" !SetextBottom1 !SetextBottom2 !@BlankLine @RawLine)+ @BlankLine* | @BlankLine+ | @RawLine)") Rules[:_ExtendedSpecialChar] = rule_info("ExtendedSpecialChar", "&{ notes? } \"^\"") Rules[:_NoteReference] = rule_info("NoteReference", "&{ notes? } RawNoteReference:ref { note_for ref }") Rules[:_RawNoteReference] = rule_info("RawNoteReference", "\"[^\" < (!@Newline !\"]\" .)+ > \"]\" { text }") Rules[:_Note] = rule_info("Note", "&{ notes? } @NonindentSpace RawNoteReference:ref \":\" @Sp @StartList:a RawNoteBlock:i { a.concat i } (&Indent RawNoteBlock:i { a.concat i })* { @footnotes[ref] = paragraph a nil }") Rules[:_InlineNote] = rule_info("InlineNote", "&{ notes? } \"^[\" @StartList:a (!\"]\" Inline:l { a << l })+ \"]\" { ref = [:inline, @note_order.length] @footnotes[ref] = paragraph a note_for ref }") Rules[:_Notes] = rule_info("Notes", "(Note | SkipBlock)*") Rules[:_RawNoteBlock] = rule_info("RawNoteBlock", "@StartList:a (!@BlankLine !RawNoteReference OptionallyIndentedLine:l { a << l })+ < @BlankLine* > { a << text } { a }") Rules[:_CodeFence] = rule_info("CodeFence", "&{ github? } Ticks3 (@Sp StrChunk:format)? Spnl < ((!\"`\" Nonspacechar)+ | !Ticks3 /`+/ | Spacechar | @Newline)+ > Ticks3 @Sp @Newline* { verbatim = RDoc::Markup::Verbatim.new text verbatim.format = format.intern if format.instance_of?(String) verbatim }") Rules[:_Table] = rule_info("Table", "&{ github? } TableHead:header TableLine:line TableRow+:body { table = RDoc::Markup::Table.new(header, line, body) }") Rules[:_TableHead] = rule_info("TableHead", "TableItem2+:items \"|\"? @Newline { items }") Rules[:_TableRow] = rule_info("TableRow", "((TableItem:item1 TableItem2*:items { [item1, *items] }):row | TableItem2+:row) \"|\"? @Newline { row }") Rules[:_TableItem2] = rule_info("TableItem2", "\"|\" TableItem") Rules[:_TableItem] = rule_info("TableItem", "< /(?:\\\\.|[^|\\n])+/ > { text.strip.gsub(/\\\\(.)/, '\\1') }") Rules[:_TableLine] = rule_info("TableLine", "((TableAlign:align1 TableAlign2*:aligns {[align1, *aligns] }):line | TableAlign2+:line) \"|\"? @Newline { line }") Rules[:_TableAlign2] = rule_info("TableAlign2", "\"|\" @Sp TableAlign") Rules[:_TableAlign] = rule_info("TableAlign", "< /:?-+:?/ > @Sp { text.start_with?(\":\") ? (text.end_with?(\":\") ? :center : :left) : (text.end_with?(\":\") ? :right : nil) }") Rules[:_DefinitionList] = rule_info("DefinitionList", "&{ definition_lists? } DefinitionListItem+:list { RDoc::Markup::List.new :NOTE, *list.flatten }") Rules[:_DefinitionListItem] = rule_info("DefinitionListItem", "DefinitionListLabel+:label DefinitionListDefinition+:defns { list_items = [] list_items << RDoc::Markup::ListItem.new(label, defns.shift) list_items.concat defns.map { |defn| RDoc::Markup::ListItem.new nil, defn } unless list_items.empty? list_items }") Rules[:_DefinitionListLabel] = rule_info("DefinitionListLabel", "StrChunk:label @Sp @Newline { label }") Rules[:_DefinitionListDefinition] = rule_info("DefinitionListDefinition", "@NonindentSpace \":\" @Space Inlines:a @BlankLine+ { paragraph a }") # :startdoc: end PK!e3 token_stream.rbnu[# frozen_string_literal: true ## # A TokenStream is a list of tokens, gathered during the parse of some entity # (say a method). Entities populate these streams by being registered with the # lexer. Any class can collect tokens by including TokenStream. From the # outside, you use such an object by calling the start_collecting_tokens # method, followed by calls to add_token and pop_token. module RDoc::TokenStream ## # Converts +token_stream+ to HTML wrapping various tokens with # elements. Some tokens types are wrapped in spans # with the given class names. Other token types are not wrapped in spans. def self.to_html token_stream starting_title = false token_stream.map do |t| next unless t style = case t[:kind] when :on_const then 'ruby-constant' when :on_kw then 'ruby-keyword' when :on_ivar then 'ruby-ivar' when :on_cvar then 'ruby-identifier' when :on_gvar then 'ruby-identifier' when '=' != t[:text] && :on_op then 'ruby-operator' when :on_tlambda then 'ruby-operator' when :on_ident then 'ruby-identifier' when :on_label then 'ruby-value' when :on_backref, :on_dstring then 'ruby-node' when :on_comment then 'ruby-comment' when :on_embdoc then 'ruby-comment' when :on_regexp then 'ruby-regexp' when :on_tstring then 'ruby-string' when :on_int, :on_float, :on_rational, :on_imaginary, :on_heredoc, :on_symbol, :on_CHAR then 'ruby-value' when :on_heredoc_beg, :on_heredoc_end then 'ruby-identifier' end comment_with_nl = false if :on_comment == t[:kind] or :on_embdoc == t[:kind] or :on_heredoc_end == t[:kind] comment_with_nl = true if "\n" == t[:text][-1] text = t[:text].rstrip else text = t[:text] end if :on_ident == t[:kind] && starting_title starting_title = false style = 'ruby-identifier ruby-title' end if :on_kw == t[:kind] and 'def' == t[:text] starting_title = true end text = CGI.escapeHTML text if style then "#{text}#{"\n" if comment_with_nl}" else text end end.join end ## # Adds +tokens+ to the collected tokens def add_tokens(tokens) @token_stream.concat(tokens) end ## # Adds one +token+ to the collected tokens def add_token(token) @token_stream.push(token) end ## # Starts collecting tokens def collect_tokens @token_stream = [] end alias start_collecting_tokens collect_tokens ## # Remove the last token from the collected tokens def pop_token @token_stream.pop end ## # Current token stream def token_stream @token_stream end ## # Returns a string representation of the token stream def tokens_to_s token_stream.compact.map { |token| token[:text] }.join '' end end PK!H"-- top_level.rbnu[# 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: ## # This TopLevel's File::Stat struct attr_accessor :file_stat ## # 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 attr_accessor :diagram # :nodoc: ## # 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 @file_stat = File.stat(absolute_name) rescue nil # HACK for testing @diagram = nil @parser = nil @classes_or_modules = [] end 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(prefix) path = [prefix, @relative_name.tr('.', '_')] File.join(*path.compact) + '.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 ## # Time this file was last modified, if known def last_modified @file_stat ? file_stat.mtime : nil 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 = array[3] @file_stat = nil 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 http_url @store.rdoc.generator.file_dir 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 PK!#@@stats/quiet.rbnu[# frozen_string_literal: true ## # Stats printer that prints nothing class RDoc::Stats::Quiet ## # Creates a new Quiet that will print nothing def initialize num_files @num_files = num_files end ## # Prints a message at the beginning of parsing def begin_adding(*) end ## # Prints when an alias is added def print_alias(*) end ## # Prints when an attribute is added def print_attribute(*) end ## # Prints when a class is added def print_class(*) end ## # Prints when a constant is added def print_constant(*) end ## # Prints when a file is added def print_file(*) end ## # Prints when a method is added def print_method(*) end ## # Prints when a module is added def print_module(*) end ## # Prints when RDoc is done def done_adding(*) end end PK! stats/verbose.rbnu[# frozen_string_literal: true ## # Stats printer that prints everything documented, including the documented # status class RDoc::Stats::Verbose < RDoc::Stats::Normal ## # Returns a marker for RDoc::CodeObject +co+ being undocumented def nodoc co " (undocumented)" unless co.documented? end def print_alias as # :nodoc: puts " alias #{as.new_name} #{as.old_name}#{nodoc as}" end def print_attribute attribute # :nodoc: puts " #{attribute.definition} #{attribute.name}#{nodoc attribute}" end def print_class(klass) # :nodoc: puts " class #{klass.full_name}#{nodoc klass}" end def print_constant(constant) # :nodoc: puts " #{constant.name}#{nodoc constant}" end def print_file(files_so_far, file) # :nodoc: super puts end def print_method(method) # :nodoc: puts " #{method.singleton ? '::' : '#'}#{method.name}#{nodoc method}" end def print_module(mod) # :nodoc: puts " module #{mod.full_name}#{nodoc mod}" end end PK!9)-$00stats/normal.rbnu[# frozen_string_literal: true begin require 'io/console/size' rescue LoadError # for JRuby require 'io/console' end ## # Stats printer that prints just the files being documented with a progress # bar class RDoc::Stats::Normal < RDoc::Stats::Quiet def begin_adding # :nodoc: puts "Parsing sources..." @last_width = 0 end ## # Prints a file with a progress bar def print_file files_so_far, filename progress_bar = sprintf("%3d%% [%2d/%2d] ", 100 * files_so_far / @num_files, files_so_far, @num_files) if $stdout.tty? # Print a progress bar, but make sure it fits on a single line. Filename # will be truncated if necessary. size = IO.respond_to?(:console_size) ? IO.console_size : IO.console.winsize terminal_width = size[1].to_i.nonzero? || 80 max_filename_size = (terminal_width - progress_bar.size) - 1 if filename.size > max_filename_size then # Turn "some_long_filename.rb" to "...ong_filename.rb" filename = filename[(filename.size - max_filename_size) .. -1] filename[0..2] = "..." end # Clean the line with whitespaces so that leftover output from the # previous line doesn't show up. $stdout.print("\r\e[K") if @last_width && @last_width > 0 @last_width = progress_bar.size + filename.size term = "\r" else term = "\n" end $stdout.print(progress_bar, filename, term) $stdout.flush end def done_adding # :nodoc: puts end end PK!R:context/section.rbnu[# frozen_string_literal: true require 'cgi/util' ## # 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 comment = extract_comment comment return if comment.empty? case comment when RDoc::Comment then @comments << comment when RDoc::Markup::Document then @comments.concat comment.parts when Array then @comments.concat comment else raise TypeError, "unknown comment type: #{comment.inspect}" 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 Array then comment.map do |c| extract_comment c end 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 when RDoc::Markup::Document then 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 return [] if @comments.empty? case @comments when Array then @comments.map do |comment| comment.file end when RDoc::Markup::Document then @comment.parts.map do |document| document.file end else raise RDoc::Error, "BUG: unknown comment class #{@comments.class}" end 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] end ## # Parses +comment_location+ into an RDoc::Markup::Document composed of # multiple RDoc::Markup::Documents with their file set. def parse case @comments when String then super when Array then docs = @comments.map do |comment, location| doc = super comment doc.file = location if location doc end RDoc::Markup::Document.new(*docs) when RDoc::Comment then doc = super @comments.text, comments.format doc.file = @comments.location doc when RDoc::Markup::Document then return @comments else raise ArgumentError, "unknown comment class #{comments.class}" end 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 comment return if @comments.empty? case @comments when Array then @comments.delete_if do |my_comment| my_comment.file == comment.file end when RDoc::Markup::Document then @comments.parts.delete_if do |document| document.file == comment.file.name end else raise RDoc::Error, "BUG: unknown comment class #{@comments.class}" end end end PK!code_objects.rbnu[# frozen_string_literal: true # This file was used to load all the RDoc::CodeObject subclasses at once. Now # autoload handles this. require_relative '../rdoc' PK!R5ghost_method.rbnu[# frozen_string_literal: true ## # GhostMethod represents a method referenced only by a comment class RDoc::GhostMethod < RDoc::AnyMethod end PK!^ any_method.rbnu[# 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 # Parameters for this method attr_accessor :params ## # 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 super @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 method.record_location an_alias.file method.singleton = self.singleton 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.empty? @call_seq = 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 = 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, comment| add_alias RDoc::Alias.new(nil, @name, new_name, comment, @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 ## # 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 PK!c7 comment.rbnu[# 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::Markup@Other+directives for instructions on adding an alternate # 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 method # 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 @text =~ /^\s*:?call-seq:(.*?(?:\S).*?)^\s*$/m then all_start, all_stop = $~.offset(0) seq_start, seq_stop = $~.offset(1) # we get the following lines that start with the leading word at the # same indent, even if they have blank lines before if $1 =~ /(^\s*\n)+^(\s*\w+)/m then leading = $2 # ' * ARGF' in the example above re = %r% \A( (^\s*\n)+ (^#{Regexp.escape leading}.*?\n)+ )+ ^\s*$ %xm if @text[seq_stop..-1] =~ re then all_stop = seq_stop + $~.offset(0).last seq_stop = seq_stop + $~.offset(1).last end end seq = @text[seq_start..seq_stop] seq.gsub!(/^\s*(\S|\n)/m, '\1') @text.slice! all_start...all_stop method.call_seq = seq.chomp else regexp = /^\s*:?call-seq:(.*?)(^\s*$|\z)/m if regexp =~ @text then @text = @text.sub(regexp, '') seq = $1 seq.gsub!(/^\s*/, '') method.call_seq = seq end end method end ## # A comment is empty if its text String is empty. def empty? @text.empty? end ## # HACK dubious def encode! encoding # TODO: Remove this condition after Ruby 2.2 EOL if RUBY_VERSION < '2.3.0' @text = @text.force_encoding encoding else @text = String.new @text, encoding: encoding end 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 end PK!Wsingle_class.rbnu[# 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 PK!OG!!markdown/entities.rbnu[# frozen_string_literal: true ## # HTML entity name map for RDoc::Markdown RDoc::Markdown::HTML_ENTITIES = { "AElig" => [0x000C6], "AMP" => [0x00026], "Aacute" => [0x000C1], "Abreve" => [0x00102], "Acirc" => [0x000C2], "Acy" => [0x00410], "Afr" => [0x1D504], "Agrave" => [0x000C0], "Alpha" => [0x00391], "Amacr" => [0x00100], "And" => [0x02A53], "Aogon" => [0x00104], "Aopf" => [0x1D538], "ApplyFunction" => [0x02061], "Aring" => [0x000C5], "Ascr" => [0x1D49C], "Assign" => [0x02254], "Atilde" => [0x000C3], "Auml" => [0x000C4], "Backslash" => [0x02216], "Barv" => [0x02AE7], "Barwed" => [0x02306], "Bcy" => [0x00411], "Because" => [0x02235], "Bernoullis" => [0x0212C], "Beta" => [0x00392], "Bfr" => [0x1D505], "Bopf" => [0x1D539], "Breve" => [0x002D8], "Bscr" => [0x0212C], "Bumpeq" => [0x0224E], "CHcy" => [0x00427], "COPY" => [0x000A9], "Cacute" => [0x00106], "Cap" => [0x022D2], "CapitalDifferentialD" => [0x02145], "Cayleys" => [0x0212D], "Ccaron" => [0x0010C], "Ccedil" => [0x000C7], "Ccirc" => [0x00108], "Cconint" => [0x02230], "Cdot" => [0x0010A], "Cedilla" => [0x000B8], "CenterDot" => [0x000B7], "Cfr" => [0x0212D], "Chi" => [0x003A7], "CircleDot" => [0x02299], "CircleMinus" => [0x02296], "CirclePlus" => [0x02295], "CircleTimes" => [0x02297], "ClockwiseContourIntegral" => [0x02232], "CloseCurlyDoubleQuote" => [0x0201D], "CloseCurlyQuote" => [0x02019], "Colon" => [0x02237], "Colone" => [0x02A74], "Congruent" => [0x02261], "Conint" => [0x0222F], "ContourIntegral" => [0x0222E], "Copf" => [0x02102], "Coproduct" => [0x02210], "CounterClockwiseContourIntegral" => [0x02233], "Cross" => [0x02A2F], "Cscr" => [0x1D49E], "Cup" => [0x022D3], "CupCap" => [0x0224D], "DD" => [0x02145], "DDotrahd" => [0x02911], "DJcy" => [0x00402], "DScy" => [0x00405], "DZcy" => [0x0040F], "Dagger" => [0x02021], "Darr" => [0x021A1], "Dashv" => [0x02AE4], "Dcaron" => [0x0010E], "Dcy" => [0x00414], "Del" => [0x02207], "Delta" => [0x00394], "Dfr" => [0x1D507], "DiacriticalAcute" => [0x000B4], "DiacriticalDot" => [0x002D9], "DiacriticalDoubleAcute" => [0x002DD], "DiacriticalGrave" => [0x00060], "DiacriticalTilde" => [0x002DC], "Diamond" => [0x022C4], "DifferentialD" => [0x02146], "Dopf" => [0x1D53B], "Dot" => [0x000A8], "DotDot" => [0x020DC], "DotEqual" => [0x02250], "DoubleContourIntegral" => [0x0222F], "DoubleDot" => [0x000A8], "DoubleDownArrow" => [0x021D3], "DoubleLeftArrow" => [0x021D0], "DoubleLeftRightArrow" => [0x021D4], "DoubleLeftTee" => [0x02AE4], "DoubleLongLeftArrow" => [0x027F8], "DoubleLongLeftRightArrow" => [0x027FA], "DoubleLongRightArrow" => [0x027F9], "DoubleRightArrow" => [0x021D2], "DoubleRightTee" => [0x022A8], "DoubleUpArrow" => [0x021D1], "DoubleUpDownArrow" => [0x021D5], "DoubleVerticalBar" => [0x02225], "DownArrow" => [0x02193], "DownArrowBar" => [0x02913], "DownArrowUpArrow" => [0x021F5], "DownBreve" => [0x00311], "DownLeftRightVector" => [0x02950], "DownLeftTeeVector" => [0x0295E], "DownLeftVector" => [0x021BD], "DownLeftVectorBar" => [0x02956], "DownRightTeeVector" => [0x0295F], "DownRightVector" => [0x021C1], "DownRightVectorBar" => [0x02957], "DownTee" => [0x022A4], "DownTeeArrow" => [0x021A7], "Downarrow" => [0x021D3], "Dscr" => [0x1D49F], "Dstrok" => [0x00110], "ENG" => [0x0014A], "ETH" => [0x000D0], "Eacute" => [0x000C9], "Ecaron" => [0x0011A], "Ecirc" => [0x000CA], "Ecy" => [0x0042D], "Edot" => [0x00116], "Efr" => [0x1D508], "Egrave" => [0x000C8], "Element" => [0x02208], "Emacr" => [0x00112], "EmptySmallSquare" => [0x025FB], "EmptyVerySmallSquare" => [0x025AB], "Eogon" => [0x00118], "Eopf" => [0x1D53C], "Epsilon" => [0x00395], "Equal" => [0x02A75], "EqualTilde" => [0x02242], "Equilibrium" => [0x021CC], "Escr" => [0x02130], "Esim" => [0x02A73], "Eta" => [0x00397], "Euml" => [0x000CB], "Exists" => [0x02203], "ExponentialE" => [0x02147], "Fcy" => [0x00424], "Ffr" => [0x1D509], "FilledSmallSquare" => [0x025FC], "FilledVerySmallSquare" => [0x025AA], "Fopf" => [0x1D53D], "ForAll" => [0x02200], "Fouriertrf" => [0x02131], "Fscr" => [0x02131], "GJcy" => [0x00403], "GT" => [0x0003E], "Gamma" => [0x00393], "Gammad" => [0x003DC], "Gbreve" => [0x0011E], "Gcedil" => [0x00122], "Gcirc" => [0x0011C], "Gcy" => [0x00413], "Gdot" => [0x00120], "Gfr" => [0x1D50A], "Gg" => [0x022D9], "Gopf" => [0x1D53E], "GreaterEqual" => [0x02265], "GreaterEqualLess" => [0x022DB], "GreaterFullEqual" => [0x02267], "GreaterGreater" => [0x02AA2], "GreaterLess" => [0x02277], "GreaterSlantEqual" => [0x02A7E], "GreaterTilde" => [0x02273], "Gscr" => [0x1D4A2], "Gt" => [0x0226B], "HARDcy" => [0x0042A], "Hacek" => [0x002C7], "Hat" => [0x0005E], "Hcirc" => [0x00124], "Hfr" => [0x0210C], "HilbertSpace" => [0x0210B], "Hopf" => [0x0210D], "HorizontalLine" => [0x02500], "Hscr" => [0x0210B], "Hstrok" => [0x00126], "HumpDownHump" => [0x0224E], "HumpEqual" => [0x0224F], "IEcy" => [0x00415], "IJlig" => [0x00132], "IOcy" => [0x00401], "Iacute" => [0x000CD], "Icirc" => [0x000CE], "Icy" => [0x00418], "Idot" => [0x00130], "Ifr" => [0x02111], "Igrave" => [0x000CC], "Im" => [0x02111], "Imacr" => [0x0012A], "ImaginaryI" => [0x02148], "Implies" => [0x021D2], "Int" => [0x0222C], "Integral" => [0x0222B], "Intersection" => [0x022C2], "InvisibleComma" => [0x02063], "InvisibleTimes" => [0x02062], "Iogon" => [0x0012E], "Iopf" => [0x1D540], "Iota" => [0x00399], "Iscr" => [0x02110], "Itilde" => [0x00128], "Iukcy" => [0x00406], "Iuml" => [0x000CF], "Jcirc" => [0x00134], "Jcy" => [0x00419], "Jfr" => [0x1D50D], "Jopf" => [0x1D541], "Jscr" => [0x1D4A5], "Jsercy" => [0x00408], "Jukcy" => [0x00404], "KHcy" => [0x00425], "KJcy" => [0x0040C], "Kappa" => [0x0039A], "Kcedil" => [0x00136], "Kcy" => [0x0041A], "Kfr" => [0x1D50E], "Kopf" => [0x1D542], "Kscr" => [0x1D4A6], "LJcy" => [0x00409], "LT" => [0x0003C], "Lacute" => [0x00139], "Lambda" => [0x0039B], "Lang" => [0x027EA], "Laplacetrf" => [0x02112], "Larr" => [0x0219E], "Lcaron" => [0x0013D], "Lcedil" => [0x0013B], "Lcy" => [0x0041B], "LeftAngleBracket" => [0x027E8], "LeftArrow" => [0x02190], "LeftArrowBar" => [0x021E4], "LeftArrowRightArrow" => [0x021C6], "LeftCeiling" => [0x02308], "LeftDoubleBracket" => [0x027E6], "LeftDownTeeVector" => [0x02961], "LeftDownVector" => [0x021C3], "LeftDownVectorBar" => [0x02959], "LeftFloor" => [0x0230A], "LeftRightArrow" => [0x02194], "LeftRightVector" => [0x0294E], "LeftTee" => [0x022A3], "LeftTeeArrow" => [0x021A4], "LeftTeeVector" => [0x0295A], "LeftTriangle" => [0x022B2], "LeftTriangleBar" => [0x029CF], "LeftTriangleEqual" => [0x022B4], "LeftUpDownVector" => [0x02951], "LeftUpTeeVector" => [0x02960], "LeftUpVector" => [0x021BF], "LeftUpVectorBar" => [0x02958], "LeftVector" => [0x021BC], "LeftVectorBar" => [0x02952], "Leftarrow" => [0x021D0], "Leftrightarrow" => [0x021D4], "LessEqualGreater" => [0x022DA], "LessFullEqual" => [0x02266], "LessGreater" => [0x02276], "LessLess" => [0x02AA1], "LessSlantEqual" => [0x02A7D], "LessTilde" => [0x02272], "Lfr" => [0x1D50F], "Ll" => [0x022D8], "Lleftarrow" => [0x021DA], "Lmidot" => [0x0013F], "LongLeftArrow" => [0x027F5], "LongLeftRightArrow" => [0x027F7], "LongRightArrow" => [0x027F6], "Longleftarrow" => [0x027F8], "Longleftrightarrow" => [0x027FA], "Longrightarrow" => [0x027F9], "Lopf" => [0x1D543], "LowerLeftArrow" => [0x02199], "LowerRightArrow" => [0x02198], "Lscr" => [0x02112], "Lsh" => [0x021B0], "Lstrok" => [0x00141], "Lt" => [0x0226A], "Map" => [0x02905], "Mcy" => [0x0041C], "MediumSpace" => [0x0205F], "Mellintrf" => [0x02133], "Mfr" => [0x1D510], "MinusPlus" => [0x02213], "Mopf" => [0x1D544], "Mscr" => [0x02133], "Mu" => [0x0039C], "NJcy" => [0x0040A], "Nacute" => [0x00143], "Ncaron" => [0x00147], "Ncedil" => [0x00145], "Ncy" => [0x0041D], "NegativeMediumSpace" => [0x0200B], "NegativeThickSpace" => [0x0200B], "NegativeThinSpace" => [0x0200B], "NegativeVeryThinSpace" => [0x0200B], "NestedGreaterGreater" => [0x0226B], "NestedLessLess" => [0x0226A], "NewLine" => [0x0000A], "Nfr" => [0x1D511], "NoBreak" => [0x02060], "NonBreakingSpace" => [0x000A0], "Nopf" => [0x02115], "Not" => [0x02AEC], "NotCongruent" => [0x02262], "NotCupCap" => [0x0226D], "NotDoubleVerticalBar" => [0x02226], "NotElement" => [0x02209], "NotEqual" => [0x02260], "NotEqualTilde" => [0x02242, 0x00338], "NotExists" => [0x02204], "NotGreater" => [0x0226F], "NotGreaterEqual" => [0x02271], "NotGreaterFullEqual" => [0x02267, 0x00338], "NotGreaterGreater" => [0x0226B, 0x00338], "NotGreaterLess" => [0x02279], "NotGreaterSlantEqual" => [0x02A7E, 0x00338], "NotGreaterTilde" => [0x02275], "NotHumpDownHump" => [0x0224E, 0x00338], "NotHumpEqual" => [0x0224F, 0x00338], "NotLeftTriangle" => [0x022EA], "NotLeftTriangleBar" => [0x029CF, 0x00338], "NotLeftTriangleEqual" => [0x022EC], "NotLess" => [0x0226E], "NotLessEqual" => [0x02270], "NotLessGreater" => [0x02278], "NotLessLess" => [0x0226A, 0x00338], "NotLessSlantEqual" => [0x02A7D, 0x00338], "NotLessTilde" => [0x02274], "NotNestedGreaterGreater" => [0x02AA2, 0x00338], "NotNestedLessLess" => [0x02AA1, 0x00338], "NotPrecedes" => [0x02280], "NotPrecedesEqual" => [0x02AAF, 0x00338], "NotPrecedesSlantEqual" => [0x022E0], "NotReverseElement" => [0x0220C], "NotRightTriangle" => [0x022EB], "NotRightTriangleBar" => [0x029D0, 0x00338], "NotRightTriangleEqual" => [0x022ED], "NotSquareSubset" => [0x0228F, 0x00338], "NotSquareSubsetEqual" => [0x022E2], "NotSquareSuperset" => [0x02290, 0x00338], "NotSquareSupersetEqual" => [0x022E3], "NotSubset" => [0x02282, 0x020D2], "NotSubsetEqual" => [0x02288], "NotSucceeds" => [0x02281], "NotSucceedsEqual" => [0x02AB0, 0x00338], "NotSucceedsSlantEqual" => [0x022E1], "NotSucceedsTilde" => [0x0227F, 0x00338], "NotSuperset" => [0x02283, 0x020D2], "NotSupersetEqual" => [0x02289], "NotTilde" => [0x02241], "NotTildeEqual" => [0x02244], "NotTildeFullEqual" => [0x02247], "NotTildeTilde" => [0x02249], "NotVerticalBar" => [0x02224], "Nscr" => [0x1D4A9], "Ntilde" => [0x000D1], "Nu" => [0x0039D], "OElig" => [0x00152], "Oacute" => [0x000D3], "Ocirc" => [0x000D4], "Ocy" => [0x0041E], "Odblac" => [0x00150], "Ofr" => [0x1D512], "Ograve" => [0x000D2], "Omacr" => [0x0014C], "Omega" => [0x003A9], "Omicron" => [0x0039F], "Oopf" => [0x1D546], "OpenCurlyDoubleQuote" => [0x0201C], "OpenCurlyQuote" => [0x02018], "Or" => [0x02A54], "Oscr" => [0x1D4AA], "Oslash" => [0x000D8], "Otilde" => [0x000D5], "Otimes" => [0x02A37], "Ouml" => [0x000D6], "OverBar" => [0x0203E], "OverBrace" => [0x023DE], "OverBracket" => [0x023B4], "OverParenthesis" => [0x023DC], "PartialD" => [0x02202], "Pcy" => [0x0041F], "Pfr" => [0x1D513], "Phi" => [0x003A6], "Pi" => [0x003A0], "PlusMinus" => [0x000B1], "Poincareplane" => [0x0210C], "Popf" => [0x02119], "Pr" => [0x02ABB], "Precedes" => [0x0227A], "PrecedesEqual" => [0x02AAF], "PrecedesSlantEqual" => [0x0227C], "PrecedesTilde" => [0x0227E], "Prime" => [0x02033], "Product" => [0x0220F], "Proportion" => [0x02237], "Proportional" => [0x0221D], "Pscr" => [0x1D4AB], "Psi" => [0x003A8], "QUOT" => [0x00022], "Qfr" => [0x1D514], "Qopf" => [0x0211A], "Qscr" => [0x1D4AC], "RBarr" => [0x02910], "REG" => [0x000AE], "Racute" => [0x00154], "Rang" => [0x027EB], "Rarr" => [0x021A0], "Rarrtl" => [0x02916], "Rcaron" => [0x00158], "Rcedil" => [0x00156], "Rcy" => [0x00420], "Re" => [0x0211C], "ReverseElement" => [0x0220B], "ReverseEquilibrium" => [0x021CB], "ReverseUpEquilibrium" => [0x0296F], "Rfr" => [0x0211C], "Rho" => [0x003A1], "RightAngleBracket" => [0x027E9], "RightArrow" => [0x02192], "RightArrowBar" => [0x021E5], "RightArrowLeftArrow" => [0x021C4], "RightCeiling" => [0x02309], "RightDoubleBracket" => [0x027E7], "RightDownTeeVector" => [0x0295D], "RightDownVector" => [0x021C2], "RightDownVectorBar" => [0x02955], "RightFloor" => [0x0230B], "RightTee" => [0x022A2], "RightTeeArrow" => [0x021A6], "RightTeeVector" => [0x0295B], "RightTriangle" => [0x022B3], "RightTriangleBar" => [0x029D0], "RightTriangleEqual" => [0x022B5], "RightUpDownVector" => [0x0294F], "RightUpTeeVector" => [0x0295C], "RightUpVector" => [0x021BE], "RightUpVectorBar" => [0x02954], "RightVector" => [0x021C0], "RightVectorBar" => [0x02953], "Rightarrow" => [0x021D2], "Ropf" => [0x0211D], "RoundImplies" => [0x02970], "Rrightarrow" => [0x021DB], "Rscr" => [0x0211B], "Rsh" => [0x021B1], "RuleDelayed" => [0x029F4], "SHCHcy" => [0x00429], "SHcy" => [0x00428], "SOFTcy" => [0x0042C], "Sacute" => [0x0015A], "Sc" => [0x02ABC], "Scaron" => [0x00160], "Scedil" => [0x0015E], "Scirc" => [0x0015C], "Scy" => [0x00421], "Sfr" => [0x1D516], "ShortDownArrow" => [0x02193], "ShortLeftArrow" => [0x02190], "ShortRightArrow" => [0x02192], "ShortUpArrow" => [0x02191], "Sigma" => [0x003A3], "SmallCircle" => [0x02218], "Sopf" => [0x1D54A], "Sqrt" => [0x0221A], "Square" => [0x025A1], "SquareIntersection" => [0x02293], "SquareSubset" => [0x0228F], "SquareSubsetEqual" => [0x02291], "SquareSuperset" => [0x02290], "SquareSupersetEqual" => [0x02292], "SquareUnion" => [0x02294], "Sscr" => [0x1D4AE], "Star" => [0x022C6], "Sub" => [0x022D0], "Subset" => [0x022D0], "SubsetEqual" => [0x02286], "Succeeds" => [0x0227B], "SucceedsEqual" => [0x02AB0], "SucceedsSlantEqual" => [0x0227D], "SucceedsTilde" => [0x0227F], "SuchThat" => [0x0220B], "Sum" => [0x02211], "Sup" => [0x022D1], "Superset" => [0x02283], "SupersetEqual" => [0x02287], "Supset" => [0x022D1], "THORN" => [0x000DE], "TRADE" => [0x02122], "TSHcy" => [0x0040B], "TScy" => [0x00426], "Tab" => [0x00009], "Tau" => [0x003A4], "Tcaron" => [0x00164], "Tcedil" => [0x00162], "Tcy" => [0x00422], "Tfr" => [0x1D517], "Therefore" => [0x02234], "Theta" => [0x00398], "ThickSpace" => [0x0205F, 0x0200A], "ThinSpace" => [0x02009], "Tilde" => [0x0223C], "TildeEqual" => [0x02243], "TildeFullEqual" => [0x02245], "TildeTilde" => [0x02248], "Topf" => [0x1D54B], "TripleDot" => [0x020DB], "Tscr" => [0x1D4AF], "Tstrok" => [0x00166], "Uacute" => [0x000DA], "Uarr" => [0x0219F], "Uarrocir" => [0x02949], "Ubrcy" => [0x0040E], "Ubreve" => [0x0016C], "Ucirc" => [0x000DB], "Ucy" => [0x00423], "Udblac" => [0x00170], "Ufr" => [0x1D518], "Ugrave" => [0x000D9], "Umacr" => [0x0016A], "UnderBar" => [0x0005F], "UnderBrace" => [0x023DF], "UnderBracket" => [0x023B5], "UnderParenthesis" => [0x023DD], "Union" => [0x022C3], "UnionPlus" => [0x0228E], "Uogon" => [0x00172], "Uopf" => [0x1D54C], "UpArrow" => [0x02191], "UpArrowBar" => [0x02912], "UpArrowDownArrow" => [0x021C5], "UpDownArrow" => [0x02195], "UpEquilibrium" => [0x0296E], "UpTee" => [0x022A5], "UpTeeArrow" => [0x021A5], "Uparrow" => [0x021D1], "Updownarrow" => [0x021D5], "UpperLeftArrow" => [0x02196], "UpperRightArrow" => [0x02197], "Upsi" => [0x003D2], "Upsilon" => [0x003A5], "Uring" => [0x0016E], "Uscr" => [0x1D4B0], "Utilde" => [0x00168], "Uuml" => [0x000DC], "VDash" => [0x022AB], "Vbar" => [0x02AEB], "Vcy" => [0x00412], "Vdash" => [0x022A9], "Vdashl" => [0x02AE6], "Vee" => [0x022C1], "Verbar" => [0x02016], "Vert" => [0x02016], "VerticalBar" => [0x02223], "VerticalLine" => [0x0007C], "VerticalSeparator" => [0x02758], "VerticalTilde" => [0x02240], "VeryThinSpace" => [0x0200A], "Vfr" => [0x1D519], "Vopf" => [0x1D54D], "Vscr" => [0x1D4B1], "Vvdash" => [0x022AA], "Wcirc" => [0x00174], "Wedge" => [0x022C0], "Wfr" => [0x1D51A], "Wopf" => [0x1D54E], "Wscr" => [0x1D4B2], "Xfr" => [0x1D51B], "Xi" => [0x0039E], "Xopf" => [0x1D54F], "Xscr" => [0x1D4B3], "YAcy" => [0x0042F], "YIcy" => [0x00407], "YUcy" => [0x0042E], "Yacute" => [0x000DD], "Ycirc" => [0x00176], "Ycy" => [0x0042B], "Yfr" => [0x1D51C], "Yopf" => [0x1D550], "Yscr" => [0x1D4B4], "Yuml" => [0x00178], "ZHcy" => [0x00416], "Zacute" => [0x00179], "Zcaron" => [0x0017D], "Zcy" => [0x00417], "Zdot" => [0x0017B], "ZeroWidthSpace" => [0x0200B], "Zeta" => [0x00396], "Zfr" => [0x02128], "Zopf" => [0x02124], "Zscr" => [0x1D4B5], "aacute" => [0x000E1], "abreve" => [0x00103], "ac" => [0x0223E], "acE" => [0x0223E, 0x00333], "acd" => [0x0223F], "acirc" => [0x000E2], "acute" => [0x000B4], "acy" => [0x00430], "aelig" => [0x000E6], "af" => [0x02061], "afr" => [0x1D51E], "agrave" => [0x000E0], "alefsym" => [0x02135], "aleph" => [0x02135], "alpha" => [0x003B1], "amacr" => [0x00101], "amalg" => [0x02A3F], "amp" => [0x00026], "and" => [0x02227], "andand" => [0x02A55], "andd" => [0x02A5C], "andslope" => [0x02A58], "andv" => [0x02A5A], "ang" => [0x02220], "ange" => [0x029A4], "angle" => [0x02220], "angmsd" => [0x02221], "angmsdaa" => [0x029A8], "angmsdab" => [0x029A9], "angmsdac" => [0x029AA], "angmsdad" => [0x029AB], "angmsdae" => [0x029AC], "angmsdaf" => [0x029AD], "angmsdag" => [0x029AE], "angmsdah" => [0x029AF], "angrt" => [0x0221F], "angrtvb" => [0x022BE], "angrtvbd" => [0x0299D], "angsph" => [0x02222], "angst" => [0x000C5], "angzarr" => [0x0237C], "aogon" => [0x00105], "aopf" => [0x1D552], "ap" => [0x02248], "apE" => [0x02A70], "apacir" => [0x02A6F], "ape" => [0x0224A], "apid" => [0x0224B], "apos" => [0x00027], "approx" => [0x02248], "approxeq" => [0x0224A], "aring" => [0x000E5], "ascr" => [0x1D4B6], "ast" => [0x0002A], "asymp" => [0x02248], "asympeq" => [0x0224D], "atilde" => [0x000E3], "auml" => [0x000E4], "awconint" => [0x02233], "awint" => [0x02A11], "bNot" => [0x02AED], "backcong" => [0x0224C], "backepsilon" => [0x003F6], "backprime" => [0x02035], "backsim" => [0x0223D], "backsimeq" => [0x022CD], "barvee" => [0x022BD], "barwed" => [0x02305], "barwedge" => [0x02305], "bbrk" => [0x023B5], "bbrktbrk" => [0x023B6], "bcong" => [0x0224C], "bcy" => [0x00431], "bdquo" => [0x0201E], "becaus" => [0x02235], "because" => [0x02235], "bemptyv" => [0x029B0], "bepsi" => [0x003F6], "bernou" => [0x0212C], "beta" => [0x003B2], "beth" => [0x02136], "between" => [0x0226C], "bfr" => [0x1D51F], "bigcap" => [0x022C2], "bigcirc" => [0x025EF], "bigcup" => [0x022C3], "bigodot" => [0x02A00], "bigoplus" => [0x02A01], "bigotimes" => [0x02A02], "bigsqcup" => [0x02A06], "bigstar" => [0x02605], "bigtriangledown" => [0x025BD], "bigtriangleup" => [0x025B3], "biguplus" => [0x02A04], "bigvee" => [0x022C1], "bigwedge" => [0x022C0], "bkarow" => [0x0290D], "blacklozenge" => [0x029EB], "blacksquare" => [0x025AA], "blacktriangle" => [0x025B4], "blacktriangledown" => [0x025BE], "blacktriangleleft" => [0x025C2], "blacktriangleright" => [0x025B8], "blank" => [0x02423], "blk12" => [0x02592], "blk14" => [0x02591], "blk34" => [0x02593], "block" => [0x02588], "bne" => [0x0003D, 0x020E5], "bnequiv" => [0x02261, 0x020E5], "bnot" => [0x02310], "bopf" => [0x1D553], "bot" => [0x022A5], "bottom" => [0x022A5], "bowtie" => [0x022C8], "boxDL" => [0x02557], "boxDR" => [0x02554], "boxDl" => [0x02556], "boxDr" => [0x02553], "boxH" => [0x02550], "boxHD" => [0x02566], "boxHU" => [0x02569], "boxHd" => [0x02564], "boxHu" => [0x02567], "boxUL" => [0x0255D], "boxUR" => [0x0255A], "boxUl" => [0x0255C], "boxUr" => [0x02559], "boxV" => [0x02551], "boxVH" => [0x0256C], "boxVL" => [0x02563], "boxVR" => [0x02560], "boxVh" => [0x0256B], "boxVl" => [0x02562], "boxVr" => [0x0255F], "boxbox" => [0x029C9], "boxdL" => [0x02555], "boxdR" => [0x02552], "boxdl" => [0x02510], "boxdr" => [0x0250C], "boxh" => [0x02500], "boxhD" => [0x02565], "boxhU" => [0x02568], "boxhd" => [0x0252C], "boxhu" => [0x02534], "boxminus" => [0x0229F], "boxplus" => [0x0229E], "boxtimes" => [0x022A0], "boxuL" => [0x0255B], "boxuR" => [0x02558], "boxul" => [0x02518], "boxur" => [0x02514], "boxv" => [0x02502], "boxvH" => [0x0256A], "boxvL" => [0x02561], "boxvR" => [0x0255E], "boxvh" => [0x0253C], "boxvl" => [0x02524], "boxvr" => [0x0251C], "bprime" => [0x02035], "breve" => [0x002D8], "brvbar" => [0x000A6], "bscr" => [0x1D4B7], "bsemi" => [0x0204F], "bsim" => [0x0223D], "bsime" => [0x022CD], "bsol" => [0x0005C], "bsolb" => [0x029C5], "bsolhsub" => [0x027C8], "bull" => [0x02022], "bullet" => [0x02022], "bump" => [0x0224E], "bumpE" => [0x02AAE], "bumpe" => [0x0224F], "bumpeq" => [0x0224F], "cacute" => [0x00107], "cap" => [0x02229], "capand" => [0x02A44], "capbrcup" => [0x02A49], "capcap" => [0x02A4B], "capcup" => [0x02A47], "capdot" => [0x02A40], "caps" => [0x02229, 0x0FE00], "caret" => [0x02041], "caron" => [0x002C7], "ccaps" => [0x02A4D], "ccaron" => [0x0010D], "ccedil" => [0x000E7], "ccirc" => [0x00109], "ccups" => [0x02A4C], "ccupssm" => [0x02A50], "cdot" => [0x0010B], "cedil" => [0x000B8], "cemptyv" => [0x029B2], "cent" => [0x000A2], "centerdot" => [0x000B7], "cfr" => [0x1D520], "chcy" => [0x00447], "check" => [0x02713], "checkmark" => [0x02713], "chi" => [0x003C7], "cir" => [0x025CB], "cirE" => [0x029C3], "circ" => [0x002C6], "circeq" => [0x02257], "circlearrowleft" => [0x021BA], "circlearrowright" => [0x021BB], "circledR" => [0x000AE], "circledS" => [0x024C8], "circledast" => [0x0229B], "circledcirc" => [0x0229A], "circleddash" => [0x0229D], "cire" => [0x02257], "cirfnint" => [0x02A10], "cirmid" => [0x02AEF], "cirscir" => [0x029C2], "clubs" => [0x02663], "clubsuit" => [0x02663], "colon" => [0x0003A], "colone" => [0x02254], "coloneq" => [0x02254], "comma" => [0x0002C], "commat" => [0x00040], "comp" => [0x02201], "compfn" => [0x02218], "complement" => [0x02201], "complexes" => [0x02102], "cong" => [0x02245], "congdot" => [0x02A6D], "conint" => [0x0222E], "copf" => [0x1D554], "coprod" => [0x02210], "copy" => [0x000A9], "copysr" => [0x02117], "crarr" => [0x021B5], "cross" => [0x02717], "cscr" => [0x1D4B8], "csub" => [0x02ACF], "csube" => [0x02AD1], "csup" => [0x02AD0], "csupe" => [0x02AD2], "ctdot" => [0x022EF], "cudarrl" => [0x02938], "cudarrr" => [0x02935], "cuepr" => [0x022DE], "cuesc" => [0x022DF], "cularr" => [0x021B6], "cularrp" => [0x0293D], "cup" => [0x0222A], "cupbrcap" => [0x02A48], "cupcap" => [0x02A46], "cupcup" => [0x02A4A], "cupdot" => [0x0228D], "cupor" => [0x02A45], "cups" => [0x0222A, 0x0FE00], "curarr" => [0x021B7], "curarrm" => [0x0293C], "curlyeqprec" => [0x022DE], "curlyeqsucc" => [0x022DF], "curlyvee" => [0x022CE], "curlywedge" => [0x022CF], "curren" => [0x000A4], "curvearrowleft" => [0x021B6], "curvearrowright" => [0x021B7], "cuvee" => [0x022CE], "cuwed" => [0x022CF], "cwconint" => [0x02232], "cwint" => [0x02231], "cylcty" => [0x0232D], "dArr" => [0x021D3], "dHar" => [0x02965], "dagger" => [0x02020], "daleth" => [0x02138], "darr" => [0x02193], "dash" => [0x02010], "dashv" => [0x022A3], "dbkarow" => [0x0290F], "dblac" => [0x002DD], "dcaron" => [0x0010F], "dcy" => [0x00434], "dd" => [0x02146], "ddagger" => [0x02021], "ddarr" => [0x021CA], "ddotseq" => [0x02A77], "deg" => [0x000B0], "delta" => [0x003B4], "demptyv" => [0x029B1], "dfisht" => [0x0297F], "dfr" => [0x1D521], "dharl" => [0x021C3], "dharr" => [0x021C2], "diam" => [0x022C4], "diamond" => [0x022C4], "diamondsuit" => [0x02666], "diams" => [0x02666], "die" => [0x000A8], "digamma" => [0x003DD], "disin" => [0x022F2], "div" => [0x000F7], "divide" => [0x000F7], "divideontimes" => [0x022C7], "divonx" => [0x022C7], "djcy" => [0x00452], "dlcorn" => [0x0231E], "dlcrop" => [0x0230D], "dollar" => [0x00024], "dopf" => [0x1D555], "dot" => [0x002D9], "doteq" => [0x02250], "doteqdot" => [0x02251], "dotminus" => [0x02238], "dotplus" => [0x02214], "dotsquare" => [0x022A1], "doublebarwedge" => [0x02306], "downarrow" => [0x02193], "downdownarrows" => [0x021CA], "downharpoonleft" => [0x021C3], "downharpoonright" => [0x021C2], "drbkarow" => [0x02910], "drcorn" => [0x0231F], "drcrop" => [0x0230C], "dscr" => [0x1D4B9], "dscy" => [0x00455], "dsol" => [0x029F6], "dstrok" => [0x00111], "dtdot" => [0x022F1], "dtri" => [0x025BF], "dtrif" => [0x025BE], "duarr" => [0x021F5], "duhar" => [0x0296F], "dwangle" => [0x029A6], "dzcy" => [0x0045F], "dzigrarr" => [0x027FF], "eDDot" => [0x02A77], "eDot" => [0x02251], "eacute" => [0x000E9], "easter" => [0x02A6E], "ecaron" => [0x0011B], "ecir" => [0x02256], "ecirc" => [0x000EA], "ecolon" => [0x02255], "ecy" => [0x0044D], "edot" => [0x00117], "ee" => [0x02147], "efDot" => [0x02252], "efr" => [0x1D522], "eg" => [0x02A9A], "egrave" => [0x000E8], "egs" => [0x02A96], "egsdot" => [0x02A98], "el" => [0x02A99], "elinters" => [0x023E7], "ell" => [0x02113], "els" => [0x02A95], "elsdot" => [0x02A97], "emacr" => [0x00113], "empty" => [0x02205], "emptyset" => [0x02205], "emptyv" => [0x02205], "emsp" => [0x02003], "emsp13" => [0x02004], "emsp14" => [0x02005], "eng" => [0x0014B], "ensp" => [0x02002], "eogon" => [0x00119], "eopf" => [0x1D556], "epar" => [0x022D5], "eparsl" => [0x029E3], "eplus" => [0x02A71], "epsi" => [0x003B5], "epsilon" => [0x003B5], "epsiv" => [0x003F5], "eqcirc" => [0x02256], "eqcolon" => [0x02255], "eqsim" => [0x02242], "eqslantgtr" => [0x02A96], "eqslantless" => [0x02A95], "equals" => [0x0003D], "equest" => [0x0225F], "equiv" => [0x02261], "equivDD" => [0x02A78], "eqvparsl" => [0x029E5], "erDot" => [0x02253], "erarr" => [0x02971], "escr" => [0x0212F], "esdot" => [0x02250], "esim" => [0x02242], "eta" => [0x003B7], "eth" => [0x000F0], "euml" => [0x000EB], "euro" => [0x020AC], "excl" => [0x00021], "exist" => [0x02203], "expectation" => [0x02130], "exponentiale" => [0x02147], "fallingdotseq" => [0x02252], "fcy" => [0x00444], "female" => [0x02640], "ffilig" => [0x0FB03], "fflig" => [0x0FB00], "ffllig" => [0x0FB04], "ffr" => [0x1D523], "filig" => [0x0FB01], "fjlig" => [0x00066, 0x0006A], "flat" => [0x0266D], "fllig" => [0x0FB02], "fltns" => [0x025B1], "fnof" => [0x00192], "fopf" => [0x1D557], "forall" => [0x02200], "fork" => [0x022D4], "forkv" => [0x02AD9], "fpartint" => [0x02A0D], "frac12" => [0x000BD], "frac13" => [0x02153], "frac14" => [0x000BC], "frac15" => [0x02155], "frac16" => [0x02159], "frac18" => [0x0215B], "frac23" => [0x02154], "frac25" => [0x02156], "frac34" => [0x000BE], "frac35" => [0x02157], "frac38" => [0x0215C], "frac45" => [0x02158], "frac56" => [0x0215A], "frac58" => [0x0215D], "frac78" => [0x0215E], "frasl" => [0x02044], "frown" => [0x02322], "fscr" => [0x1D4BB], "gE" => [0x02267], "gEl" => [0x02A8C], "gacute" => [0x001F5], "gamma" => [0x003B3], "gammad" => [0x003DD], "gap" => [0x02A86], "gbreve" => [0x0011F], "gcirc" => [0x0011D], "gcy" => [0x00433], "gdot" => [0x00121], "ge" => [0x02265], "gel" => [0x022DB], "geq" => [0x02265], "geqq" => [0x02267], "geqslant" => [0x02A7E], "ges" => [0x02A7E], "gescc" => [0x02AA9], "gesdot" => [0x02A80], "gesdoto" => [0x02A82], "gesdotol" => [0x02A84], "gesl" => [0x022DB, 0x0FE00], "gesles" => [0x02A94], "gfr" => [0x1D524], "gg" => [0x0226B], "ggg" => [0x022D9], "gimel" => [0x02137], "gjcy" => [0x00453], "gl" => [0x02277], "glE" => [0x02A92], "gla" => [0x02AA5], "glj" => [0x02AA4], "gnE" => [0x02269], "gnap" => [0x02A8A], "gnapprox" => [0x02A8A], "gne" => [0x02A88], "gneq" => [0x02A88], "gneqq" => [0x02269], "gnsim" => [0x022E7], "gopf" => [0x1D558], "grave" => [0x00060], "gscr" => [0x0210A], "gsim" => [0x02273], "gsime" => [0x02A8E], "gsiml" => [0x02A90], "gt" => [0x0003E], "gtcc" => [0x02AA7], "gtcir" => [0x02A7A], "gtdot" => [0x022D7], "gtlPar" => [0x02995], "gtquest" => [0x02A7C], "gtrapprox" => [0x02A86], "gtrarr" => [0x02978], "gtrdot" => [0x022D7], "gtreqless" => [0x022DB], "gtreqqless" => [0x02A8C], "gtrless" => [0x02277], "gtrsim" => [0x02273], "gvertneqq" => [0x02269, 0x0FE00], "gvnE" => [0x02269, 0x0FE00], "hArr" => [0x021D4], "hairsp" => [0x0200A], "half" => [0x000BD], "hamilt" => [0x0210B], "hardcy" => [0x0044A], "harr" => [0x02194], "harrcir" => [0x02948], "harrw" => [0x021AD], "hbar" => [0x0210F], "hcirc" => [0x00125], "hearts" => [0x02665], "heartsuit" => [0x02665], "hellip" => [0x02026], "hercon" => [0x022B9], "hfr" => [0x1D525], "hksearow" => [0x02925], "hkswarow" => [0x02926], "hoarr" => [0x021FF], "homtht" => [0x0223B], "hookleftarrow" => [0x021A9], "hookrightarrow" => [0x021AA], "hopf" => [0x1D559], "horbar" => [0x02015], "hscr" => [0x1D4BD], "hslash" => [0x0210F], "hstrok" => [0x00127], "hybull" => [0x02043], "hyphen" => [0x02010], "iacute" => [0x000ED], "ic" => [0x02063], "icirc" => [0x000EE], "icy" => [0x00438], "iecy" => [0x00435], "iexcl" => [0x000A1], "iff" => [0x021D4], "ifr" => [0x1D526], "igrave" => [0x000EC], "ii" => [0x02148], "iiiint" => [0x02A0C], "iiint" => [0x0222D], "iinfin" => [0x029DC], "iiota" => [0x02129], "ijlig" => [0x00133], "imacr" => [0x0012B], "image" => [0x02111], "imagline" => [0x02110], "imagpart" => [0x02111], "imath" => [0x00131], "imof" => [0x022B7], "imped" => [0x001B5], "in" => [0x02208], "incare" => [0x02105], "infin" => [0x0221E], "infintie" => [0x029DD], "inodot" => [0x00131], "int" => [0x0222B], "intcal" => [0x022BA], "integers" => [0x02124], "intercal" => [0x022BA], "intlarhk" => [0x02A17], "intprod" => [0x02A3C], "iocy" => [0x00451], "iogon" => [0x0012F], "iopf" => [0x1D55A], "iota" => [0x003B9], "iprod" => [0x02A3C], "iquest" => [0x000BF], "iscr" => [0x1D4BE], "isin" => [0x02208], "isinE" => [0x022F9], "isindot" => [0x022F5], "isins" => [0x022F4], "isinsv" => [0x022F3], "isinv" => [0x02208], "it" => [0x02062], "itilde" => [0x00129], "iukcy" => [0x00456], "iuml" => [0x000EF], "jcirc" => [0x00135], "jcy" => [0x00439], "jfr" => [0x1D527], "jmath" => [0x00237], "jopf" => [0x1D55B], "jscr" => [0x1D4BF], "jsercy" => [0x00458], "jukcy" => [0x00454], "kappa" => [0x003BA], "kappav" => [0x003F0], "kcedil" => [0x00137], "kcy" => [0x0043A], "kfr" => [0x1D528], "kgreen" => [0x00138], "khcy" => [0x00445], "kjcy" => [0x0045C], "kopf" => [0x1D55C], "kscr" => [0x1D4C0], "lAarr" => [0x021DA], "lArr" => [0x021D0], "lAtail" => [0x0291B], "lBarr" => [0x0290E], "lE" => [0x02266], "lEg" => [0x02A8B], "lHar" => [0x02962], "lacute" => [0x0013A], "laemptyv" => [0x029B4], "lagran" => [0x02112], "lambda" => [0x003BB], "lang" => [0x027E8], "langd" => [0x02991], "langle" => [0x027E8], "lap" => [0x02A85], "laquo" => [0x000AB], "larr" => [0x02190], "larrb" => [0x021E4], "larrbfs" => [0x0291F], "larrfs" => [0x0291D], "larrhk" => [0x021A9], "larrlp" => [0x021AB], "larrpl" => [0x02939], "larrsim" => [0x02973], "larrtl" => [0x021A2], "lat" => [0x02AAB], "latail" => [0x02919], "late" => [0x02AAD], "lates" => [0x02AAD, 0x0FE00], "lbarr" => [0x0290C], "lbbrk" => [0x02772], "lbrace" => [0x0007B], "lbrack" => [0x0005B], "lbrke" => [0x0298B], "lbrksld" => [0x0298F], "lbrkslu" => [0x0298D], "lcaron" => [0x0013E], "lcedil" => [0x0013C], "lceil" => [0x02308], "lcub" => [0x0007B], "lcy" => [0x0043B], "ldca" => [0x02936], "ldquo" => [0x0201C], "ldquor" => [0x0201E], "ldrdhar" => [0x02967], "ldrushar" => [0x0294B], "ldsh" => [0x021B2], "le" => [0x02264], "leftarrow" => [0x02190], "leftarrowtail" => [0x021A2], "leftharpoondown" => [0x021BD], "leftharpoonup" => [0x021BC], "leftleftarrows" => [0x021C7], "leftrightarrow" => [0x02194], "leftrightarrows" => [0x021C6], "leftrightharpoons" => [0x021CB], "leftrightsquigarrow" => [0x021AD], "leftthreetimes" => [0x022CB], "leg" => [0x022DA], "leq" => [0x02264], "leqq" => [0x02266], "leqslant" => [0x02A7D], "les" => [0x02A7D], "lescc" => [0x02AA8], "lesdot" => [0x02A7F], "lesdoto" => [0x02A81], "lesdotor" => [0x02A83], "lesg" => [0x022DA, 0x0FE00], "lesges" => [0x02A93], "lessapprox" => [0x02A85], "lessdot" => [0x022D6], "lesseqgtr" => [0x022DA], "lesseqqgtr" => [0x02A8B], "lessgtr" => [0x02276], "lesssim" => [0x02272], "lfisht" => [0x0297C], "lfloor" => [0x0230A], "lfr" => [0x1D529], "lg" => [0x02276], "lgE" => [0x02A91], "lhard" => [0x021BD], "lharu" => [0x021BC], "lharul" => [0x0296A], "lhblk" => [0x02584], "ljcy" => [0x00459], "ll" => [0x0226A], "llarr" => [0x021C7], "llcorner" => [0x0231E], "llhard" => [0x0296B], "lltri" => [0x025FA], "lmidot" => [0x00140], "lmoust" => [0x023B0], "lmoustache" => [0x023B0], "lnE" => [0x02268], "lnap" => [0x02A89], "lnapprox" => [0x02A89], "lne" => [0x02A87], "lneq" => [0x02A87], "lneqq" => [0x02268], "lnsim" => [0x022E6], "loang" => [0x027EC], "loarr" => [0x021FD], "lobrk" => [0x027E6], "longleftarrow" => [0x027F5], "longleftrightarrow" => [0x027F7], "longmapsto" => [0x027FC], "longrightarrow" => [0x027F6], "looparrowleft" => [0x021AB], "looparrowright" => [0x021AC], "lopar" => [0x02985], "lopf" => [0x1D55D], "loplus" => [0x02A2D], "lotimes" => [0x02A34], "lowast" => [0x02217], "lowbar" => [0x0005F], "loz" => [0x025CA], "lozenge" => [0x025CA], "lozf" => [0x029EB], "lpar" => [0x00028], "lparlt" => [0x02993], "lrarr" => [0x021C6], "lrcorner" => [0x0231F], "lrhar" => [0x021CB], "lrhard" => [0x0296D], "lrm" => [0x0200E], "lrtri" => [0x022BF], "lsaquo" => [0x02039], "lscr" => [0x1D4C1], "lsh" => [0x021B0], "lsim" => [0x02272], "lsime" => [0x02A8D], "lsimg" => [0x02A8F], "lsqb" => [0x0005B], "lsquo" => [0x02018], "lsquor" => [0x0201A], "lstrok" => [0x00142], "lt" => [0x0003C], "ltcc" => [0x02AA6], "ltcir" => [0x02A79], "ltdot" => [0x022D6], "lthree" => [0x022CB], "ltimes" => [0x022C9], "ltlarr" => [0x02976], "ltquest" => [0x02A7B], "ltrPar" => [0x02996], "ltri" => [0x025C3], "ltrie" => [0x022B4], "ltrif" => [0x025C2], "lurdshar" => [0x0294A], "luruhar" => [0x02966], "lvertneqq" => [0x02268, 0x0FE00], "lvnE" => [0x02268, 0x0FE00], "mDDot" => [0x0223A], "macr" => [0x000AF], "male" => [0x02642], "malt" => [0x02720], "maltese" => [0x02720], "map" => [0x021A6], "mapsto" => [0x021A6], "mapstodown" => [0x021A7], "mapstoleft" => [0x021A4], "mapstoup" => [0x021A5], "marker" => [0x025AE], "mcomma" => [0x02A29], "mcy" => [0x0043C], "mdash" => [0x02014], "measuredangle" => [0x02221], "mfr" => [0x1D52A], "mho" => [0x02127], "micro" => [0x000B5], "mid" => [0x02223], "midast" => [0x0002A], "midcir" => [0x02AF0], "middot" => [0x000B7], "minus" => [0x02212], "minusb" => [0x0229F], "minusd" => [0x02238], "minusdu" => [0x02A2A], "mlcp" => [0x02ADB], "mldr" => [0x02026], "mnplus" => [0x02213], "models" => [0x022A7], "mopf" => [0x1D55E], "mp" => [0x02213], "mscr" => [0x1D4C2], "mstpos" => [0x0223E], "mu" => [0x003BC], "multimap" => [0x022B8], "mumap" => [0x022B8], "nGg" => [0x022D9, 0x00338], "nGt" => [0x0226B, 0x020D2], "nGtv" => [0x0226B, 0x00338], "nLeftarrow" => [0x021CD], "nLeftrightarrow" => [0x021CE], "nLl" => [0x022D8, 0x00338], "nLt" => [0x0226A, 0x020D2], "nLtv" => [0x0226A, 0x00338], "nRightarrow" => [0x021CF], "nVDash" => [0x022AF], "nVdash" => [0x022AE], "nabla" => [0x02207], "nacute" => [0x00144], "nang" => [0x02220, 0x020D2], "nap" => [0x02249], "napE" => [0x02A70, 0x00338], "napid" => [0x0224B, 0x00338], "napos" => [0x00149], "napprox" => [0x02249], "natur" => [0x0266E], "natural" => [0x0266E], "naturals" => [0x02115], "nbsp" => [0x000A0], "nbump" => [0x0224E, 0x00338], "nbumpe" => [0x0224F, 0x00338], "ncap" => [0x02A43], "ncaron" => [0x00148], "ncedil" => [0x00146], "ncong" => [0x02247], "ncongdot" => [0x02A6D, 0x00338], "ncup" => [0x02A42], "ncy" => [0x0043D], "ndash" => [0x02013], "ne" => [0x02260], "neArr" => [0x021D7], "nearhk" => [0x02924], "nearr" => [0x02197], "nearrow" => [0x02197], "nedot" => [0x02250, 0x00338], "nequiv" => [0x02262], "nesear" => [0x02928], "nesim" => [0x02242, 0x00338], "nexist" => [0x02204], "nexists" => [0x02204], "nfr" => [0x1D52B], "ngE" => [0x02267, 0x00338], "nge" => [0x02271], "ngeq" => [0x02271], "ngeqq" => [0x02267, 0x00338], "ngeqslant" => [0x02A7E, 0x00338], "nges" => [0x02A7E, 0x00338], "ngsim" => [0x02275], "ngt" => [0x0226F], "ngtr" => [0x0226F], "nhArr" => [0x021CE], "nharr" => [0x021AE], "nhpar" => [0x02AF2], "ni" => [0x0220B], "nis" => [0x022FC], "nisd" => [0x022FA], "niv" => [0x0220B], "njcy" => [0x0045A], "nlArr" => [0x021CD], "nlE" => [0x02266, 0x00338], "nlarr" => [0x0219A], "nldr" => [0x02025], "nle" => [0x02270], "nleftarrow" => [0x0219A], "nleftrightarrow" => [0x021AE], "nleq" => [0x02270], "nleqq" => [0x02266, 0x00338], "nleqslant" => [0x02A7D, 0x00338], "nles" => [0x02A7D, 0x00338], "nless" => [0x0226E], "nlsim" => [0x02274], "nlt" => [0x0226E], "nltri" => [0x022EA], "nltrie" => [0x022EC], "nmid" => [0x02224], "nopf" => [0x1D55F], "not" => [0x000AC], "notin" => [0x02209], "notinE" => [0x022F9, 0x00338], "notindot" => [0x022F5, 0x00338], "notinva" => [0x02209], "notinvb" => [0x022F7], "notinvc" => [0x022F6], "notni" => [0x0220C], "notniva" => [0x0220C], "notnivb" => [0x022FE], "notnivc" => [0x022FD], "npar" => [0x02226], "nparallel" => [0x02226], "nparsl" => [0x02AFD, 0x020E5], "npart" => [0x02202, 0x00338], "npolint" => [0x02A14], "npr" => [0x02280], "nprcue" => [0x022E0], "npre" => [0x02AAF, 0x00338], "nprec" => [0x02280], "npreceq" => [0x02AAF, 0x00338], "nrArr" => [0x021CF], "nrarr" => [0x0219B], "nrarrc" => [0x02933, 0x00338], "nrarrw" => [0x0219D, 0x00338], "nrightarrow" => [0x0219B], "nrtri" => [0x022EB], "nrtrie" => [0x022ED], "nsc" => [0x02281], "nsccue" => [0x022E1], "nsce" => [0x02AB0, 0x00338], "nscr" => [0x1D4C3], "nshortmid" => [0x02224], "nshortparallel" => [0x02226], "nsim" => [0x02241], "nsime" => [0x02244], "nsimeq" => [0x02244], "nsmid" => [0x02224], "nspar" => [0x02226], "nsqsube" => [0x022E2], "nsqsupe" => [0x022E3], "nsub" => [0x02284], "nsubE" => [0x02AC5, 0x00338], "nsube" => [0x02288], "nsubset" => [0x02282, 0x020D2], "nsubseteq" => [0x02288], "nsubseteqq" => [0x02AC5, 0x00338], "nsucc" => [0x02281], "nsucceq" => [0x02AB0, 0x00338], "nsup" => [0x02285], "nsupE" => [0x02AC6, 0x00338], "nsupe" => [0x02289], "nsupset" => [0x02283, 0x020D2], "nsupseteq" => [0x02289], "nsupseteqq" => [0x02AC6, 0x00338], "ntgl" => [0x02279], "ntilde" => [0x000F1], "ntlg" => [0x02278], "ntriangleleft" => [0x022EA], "ntrianglelefteq" => [0x022EC], "ntriangleright" => [0x022EB], "ntrianglerighteq" => [0x022ED], "nu" => [0x003BD], "num" => [0x00023], "numero" => [0x02116], "numsp" => [0x02007], "nvDash" => [0x022AD], "nvHarr" => [0x02904], "nvap" => [0x0224D, 0x020D2], "nvdash" => [0x022AC], "nvge" => [0x02265, 0x020D2], "nvgt" => [0x0003E, 0x020D2], "nvinfin" => [0x029DE], "nvlArr" => [0x02902], "nvle" => [0x02264, 0x020D2], "nvlt" => [0x0003C, 0x020D2], "nvltrie" => [0x022B4, 0x020D2], "nvrArr" => [0x02903], "nvrtrie" => [0x022B5, 0x020D2], "nvsim" => [0x0223C, 0x020D2], "nwArr" => [0x021D6], "nwarhk" => [0x02923], "nwarr" => [0x02196], "nwarrow" => [0x02196], "nwnear" => [0x02927], "oS" => [0x024C8], "oacute" => [0x000F3], "oast" => [0x0229B], "ocir" => [0x0229A], "ocirc" => [0x000F4], "ocy" => [0x0043E], "odash" => [0x0229D], "odblac" => [0x00151], "odiv" => [0x02A38], "odot" => [0x02299], "odsold" => [0x029BC], "oelig" => [0x00153], "ofcir" => [0x029BF], "ofr" => [0x1D52C], "ogon" => [0x002DB], "ograve" => [0x000F2], "ogt" => [0x029C1], "ohbar" => [0x029B5], "ohm" => [0x003A9], "oint" => [0x0222E], "olarr" => [0x021BA], "olcir" => [0x029BE], "olcross" => [0x029BB], "oline" => [0x0203E], "olt" => [0x029C0], "omacr" => [0x0014D], "omega" => [0x003C9], "omicron" => [0x003BF], "omid" => [0x029B6], "ominus" => [0x02296], "oopf" => [0x1D560], "opar" => [0x029B7], "operp" => [0x029B9], "oplus" => [0x02295], "or" => [0x02228], "orarr" => [0x021BB], "ord" => [0x02A5D], "order" => [0x02134], "orderof" => [0x02134], "ordf" => [0x000AA], "ordm" => [0x000BA], "origof" => [0x022B6], "oror" => [0x02A56], "orslope" => [0x02A57], "orv" => [0x02A5B], "oscr" => [0x02134], "oslash" => [0x000F8], "osol" => [0x02298], "otilde" => [0x000F5], "otimes" => [0x02297], "otimesas" => [0x02A36], "ouml" => [0x000F6], "ovbar" => [0x0233D], "par" => [0x02225], "para" => [0x000B6], "parallel" => [0x02225], "parsim" => [0x02AF3], "parsl" => [0x02AFD], "part" => [0x02202], "pcy" => [0x0043F], "percnt" => [0x00025], "period" => [0x0002E], "permil" => [0x02030], "perp" => [0x022A5], "pertenk" => [0x02031], "pfr" => [0x1D52D], "phi" => [0x003C6], "phiv" => [0x003D5], "phmmat" => [0x02133], "phone" => [0x0260E], "pi" => [0x003C0], "pitchfork" => [0x022D4], "piv" => [0x003D6], "planck" => [0x0210F], "planckh" => [0x0210E], "plankv" => [0x0210F], "plus" => [0x0002B], "plusacir" => [0x02A23], "plusb" => [0x0229E], "pluscir" => [0x02A22], "plusdo" => [0x02214], "plusdu" => [0x02A25], "pluse" => [0x02A72], "plusmn" => [0x000B1], "plussim" => [0x02A26], "plustwo" => [0x02A27], "pm" => [0x000B1], "pointint" => [0x02A15], "popf" => [0x1D561], "pound" => [0x000A3], "pr" => [0x0227A], "prE" => [0x02AB3], "prap" => [0x02AB7], "prcue" => [0x0227C], "pre" => [0x02AAF], "prec" => [0x0227A], "precapprox" => [0x02AB7], "preccurlyeq" => [0x0227C], "preceq" => [0x02AAF], "precnapprox" => [0x02AB9], "precneqq" => [0x02AB5], "precnsim" => [0x022E8], "precsim" => [0x0227E], "prime" => [0x02032], "primes" => [0x02119], "prnE" => [0x02AB5], "prnap" => [0x02AB9], "prnsim" => [0x022E8], "prod" => [0x0220F], "profalar" => [0x0232E], "profline" => [0x02312], "profsurf" => [0x02313], "prop" => [0x0221D], "propto" => [0x0221D], "prsim" => [0x0227E], "prurel" => [0x022B0], "pscr" => [0x1D4C5], "psi" => [0x003C8], "puncsp" => [0x02008], "qfr" => [0x1D52E], "qint" => [0x02A0C], "qopf" => [0x1D562], "qprime" => [0x02057], "qscr" => [0x1D4C6], "quaternions" => [0x0210D], "quatint" => [0x02A16], "quest" => [0x0003F], "questeq" => [0x0225F], "quot" => [0x00022], "rAarr" => [0x021DB], "rArr" => [0x021D2], "rAtail" => [0x0291C], "rBarr" => [0x0290F], "rHar" => [0x02964], "race" => [0x0223D, 0x00331], "racute" => [0x00155], "radic" => [0x0221A], "raemptyv" => [0x029B3], "rang" => [0x027E9], "rangd" => [0x02992], "range" => [0x029A5], "rangle" => [0x027E9], "raquo" => [0x000BB], "rarr" => [0x02192], "rarrap" => [0x02975], "rarrb" => [0x021E5], "rarrbfs" => [0x02920], "rarrc" => [0x02933], "rarrfs" => [0x0291E], "rarrhk" => [0x021AA], "rarrlp" => [0x021AC], "rarrpl" => [0x02945], "rarrsim" => [0x02974], "rarrtl" => [0x021A3], "rarrw" => [0x0219D], "ratail" => [0x0291A], "ratio" => [0x02236], "rationals" => [0x0211A], "rbarr" => [0x0290D], "rbbrk" => [0x02773], "rbrace" => [0x0007D], "rbrack" => [0x0005D], "rbrke" => [0x0298C], "rbrksld" => [0x0298E], "rbrkslu" => [0x02990], "rcaron" => [0x00159], "rcedil" => [0x00157], "rceil" => [0x02309], "rcub" => [0x0007D], "rcy" => [0x00440], "rdca" => [0x02937], "rdldhar" => [0x02969], "rdquo" => [0x0201D], "rdquor" => [0x0201D], "rdsh" => [0x021B3], "real" => [0x0211C], "realine" => [0x0211B], "realpart" => [0x0211C], "reals" => [0x0211D], "rect" => [0x025AD], "reg" => [0x000AE], "rfisht" => [0x0297D], "rfloor" => [0x0230B], "rfr" => [0x1D52F], "rhard" => [0x021C1], "rharu" => [0x021C0], "rharul" => [0x0296C], "rho" => [0x003C1], "rhov" => [0x003F1], "rightarrow" => [0x02192], "rightarrowtail" => [0x021A3], "rightharpoondown" => [0x021C1], "rightharpoonup" => [0x021C0], "rightleftarrows" => [0x021C4], "rightleftharpoons" => [0x021CC], "rightrightarrows" => [0x021C9], "rightsquigarrow" => [0x0219D], "rightthreetimes" => [0x022CC], "ring" => [0x002DA], "risingdotseq" => [0x02253], "rlarr" => [0x021C4], "rlhar" => [0x021CC], "rlm" => [0x0200F], "rmoust" => [0x023B1], "rmoustache" => [0x023B1], "rnmid" => [0x02AEE], "roang" => [0x027ED], "roarr" => [0x021FE], "robrk" => [0x027E7], "ropar" => [0x02986], "ropf" => [0x1D563], "roplus" => [0x02A2E], "rotimes" => [0x02A35], "rpar" => [0x00029], "rpargt" => [0x02994], "rppolint" => [0x02A12], "rrarr" => [0x021C9], "rsaquo" => [0x0203A], "rscr" => [0x1D4C7], "rsh" => [0x021B1], "rsqb" => [0x0005D], "rsquo" => [0x02019], "rsquor" => [0x02019], "rthree" => [0x022CC], "rtimes" => [0x022CA], "rtri" => [0x025B9], "rtrie" => [0x022B5], "rtrif" => [0x025B8], "rtriltri" => [0x029CE], "ruluhar" => [0x02968], "rx" => [0x0211E], "sacute" => [0x0015B], "sbquo" => [0x0201A], "sc" => [0x0227B], "scE" => [0x02AB4], "scap" => [0x02AB8], "scaron" => [0x00161], "sccue" => [0x0227D], "sce" => [0x02AB0], "scedil" => [0x0015F], "scirc" => [0x0015D], "scnE" => [0x02AB6], "scnap" => [0x02ABA], "scnsim" => [0x022E9], "scpolint" => [0x02A13], "scsim" => [0x0227F], "scy" => [0x00441], "sdot" => [0x022C5], "sdotb" => [0x022A1], "sdote" => [0x02A66], "seArr" => [0x021D8], "searhk" => [0x02925], "searr" => [0x02198], "searrow" => [0x02198], "sect" => [0x000A7], "semi" => [0x0003B], "seswar" => [0x02929], "setminus" => [0x02216], "setmn" => [0x02216], "sext" => [0x02736], "sfr" => [0x1D530], "sfrown" => [0x02322], "sharp" => [0x0266F], "shchcy" => [0x00449], "shcy" => [0x00448], "shortmid" => [0x02223], "shortparallel" => [0x02225], "shy" => [0x000AD], "sigma" => [0x003C3], "sigmaf" => [0x003C2], "sigmav" => [0x003C2], "sim" => [0x0223C], "simdot" => [0x02A6A], "sime" => [0x02243], "simeq" => [0x02243], "simg" => [0x02A9E], "simgE" => [0x02AA0], "siml" => [0x02A9D], "simlE" => [0x02A9F], "simne" => [0x02246], "simplus" => [0x02A24], "simrarr" => [0x02972], "slarr" => [0x02190], "smallsetminus" => [0x02216], "smashp" => [0x02A33], "smeparsl" => [0x029E4], "smid" => [0x02223], "smile" => [0x02323], "smt" => [0x02AAA], "smte" => [0x02AAC], "smtes" => [0x02AAC, 0x0FE00], "softcy" => [0x0044C], "sol" => [0x0002F], "solb" => [0x029C4], "solbar" => [0x0233F], "sopf" => [0x1D564], "spades" => [0x02660], "spadesuit" => [0x02660], "spar" => [0x02225], "sqcap" => [0x02293], "sqcaps" => [0x02293, 0x0FE00], "sqcup" => [0x02294], "sqcups" => [0x02294, 0x0FE00], "sqsub" => [0x0228F], "sqsube" => [0x02291], "sqsubset" => [0x0228F], "sqsubseteq" => [0x02291], "sqsup" => [0x02290], "sqsupe" => [0x02292], "sqsupset" => [0x02290], "sqsupseteq" => [0x02292], "squ" => [0x025A1], "square" => [0x025A1], "squarf" => [0x025AA], "squf" => [0x025AA], "srarr" => [0x02192], "sscr" => [0x1D4C8], "ssetmn" => [0x02216], "ssmile" => [0x02323], "sstarf" => [0x022C6], "star" => [0x02606], "starf" => [0x02605], "straightepsilon" => [0x003F5], "straightphi" => [0x003D5], "strns" => [0x000AF], "sub" => [0x02282], "subE" => [0x02AC5], "subdot" => [0x02ABD], "sube" => [0x02286], "subedot" => [0x02AC3], "submult" => [0x02AC1], "subnE" => [0x02ACB], "subne" => [0x0228A], "subplus" => [0x02ABF], "subrarr" => [0x02979], "subset" => [0x02282], "subseteq" => [0x02286], "subseteqq" => [0x02AC5], "subsetneq" => [0x0228A], "subsetneqq" => [0x02ACB], "subsim" => [0x02AC7], "subsub" => [0x02AD5], "subsup" => [0x02AD3], "succ" => [0x0227B], "succapprox" => [0x02AB8], "succcurlyeq" => [0x0227D], "succeq" => [0x02AB0], "succnapprox" => [0x02ABA], "succneqq" => [0x02AB6], "succnsim" => [0x022E9], "succsim" => [0x0227F], "sum" => [0x02211], "sung" => [0x0266A], "sup" => [0x02283], "sup1" => [0x000B9], "sup2" => [0x000B2], "sup3" => [0x000B3], "supE" => [0x02AC6], "supdot" => [0x02ABE], "supdsub" => [0x02AD8], "supe" => [0x02287], "supedot" => [0x02AC4], "suphsol" => [0x027C9], "suphsub" => [0x02AD7], "suplarr" => [0x0297B], "supmult" => [0x02AC2], "supnE" => [0x02ACC], "supne" => [0x0228B], "supplus" => [0x02AC0], "supset" => [0x02283], "supseteq" => [0x02287], "supseteqq" => [0x02AC6], "supsetneq" => [0x0228B], "supsetneqq" => [0x02ACC], "supsim" => [0x02AC8], "supsub" => [0x02AD4], "supsup" => [0x02AD6], "swArr" => [0x021D9], "swarhk" => [0x02926], "swarr" => [0x02199], "swarrow" => [0x02199], "swnwar" => [0x0292A], "szlig" => [0x000DF], "target" => [0x02316], "tau" => [0x003C4], "tbrk" => [0x023B4], "tcaron" => [0x00165], "tcedil" => [0x00163], "tcy" => [0x00442], "tdot" => [0x020DB], "telrec" => [0x02315], "tfr" => [0x1D531], "there4" => [0x02234], "therefore" => [0x02234], "theta" => [0x003B8], "thetasym" => [0x003D1], "thetav" => [0x003D1], "thickapprox" => [0x02248], "thicksim" => [0x0223C], "thinsp" => [0x02009], "thkap" => [0x02248], "thksim" => [0x0223C], "thorn" => [0x000FE], "tilde" => [0x002DC], "times" => [0x000D7], "timesb" => [0x022A0], "timesbar" => [0x02A31], "timesd" => [0x02A30], "tint" => [0x0222D], "toea" => [0x02928], "top" => [0x022A4], "topbot" => [0x02336], "topcir" => [0x02AF1], "topf" => [0x1D565], "topfork" => [0x02ADA], "tosa" => [0x02929], "tprime" => [0x02034], "trade" => [0x02122], "triangle" => [0x025B5], "triangledown" => [0x025BF], "triangleleft" => [0x025C3], "trianglelefteq" => [0x022B4], "triangleq" => [0x0225C], "triangleright" => [0x025B9], "trianglerighteq" => [0x022B5], "tridot" => [0x025EC], "trie" => [0x0225C], "triminus" => [0x02A3A], "triplus" => [0x02A39], "trisb" => [0x029CD], "tritime" => [0x02A3B], "trpezium" => [0x023E2], "tscr" => [0x1D4C9], "tscy" => [0x00446], "tshcy" => [0x0045B], "tstrok" => [0x00167], "twixt" => [0x0226C], "twoheadleftarrow" => [0x0219E], "twoheadrightarrow" => [0x021A0], "uArr" => [0x021D1], "uHar" => [0x02963], "uacute" => [0x000FA], "uarr" => [0x02191], "ubrcy" => [0x0045E], "ubreve" => [0x0016D], "ucirc" => [0x000FB], "ucy" => [0x00443], "udarr" => [0x021C5], "udblac" => [0x00171], "udhar" => [0x0296E], "ufisht" => [0x0297E], "ufr" => [0x1D532], "ugrave" => [0x000F9], "uharl" => [0x021BF], "uharr" => [0x021BE], "uhblk" => [0x02580], "ulcorn" => [0x0231C], "ulcorner" => [0x0231C], "ulcrop" => [0x0230F], "ultri" => [0x025F8], "umacr" => [0x0016B], "uml" => [0x000A8], "uogon" => [0x00173], "uopf" => [0x1D566], "uparrow" => [0x02191], "updownarrow" => [0x02195], "upharpoonleft" => [0x021BF], "upharpoonright" => [0x021BE], "uplus" => [0x0228E], "upsi" => [0x003C5], "upsih" => [0x003D2], "upsilon" => [0x003C5], "upuparrows" => [0x021C8], "urcorn" => [0x0231D], "urcorner" => [0x0231D], "urcrop" => [0x0230E], "uring" => [0x0016F], "urtri" => [0x025F9], "uscr" => [0x1D4CA], "utdot" => [0x022F0], "utilde" => [0x00169], "utri" => [0x025B5], "utrif" => [0x025B4], "uuarr" => [0x021C8], "uuml" => [0x000FC], "uwangle" => [0x029A7], "vArr" => [0x021D5], "vBar" => [0x02AE8], "vBarv" => [0x02AE9], "vDash" => [0x022A8], "vangrt" => [0x0299C], "varepsilon" => [0x003F5], "varkappa" => [0x003F0], "varnothing" => [0x02205], "varphi" => [0x003D5], "varpi" => [0x003D6], "varpropto" => [0x0221D], "varr" => [0x02195], "varrho" => [0x003F1], "varsigma" => [0x003C2], "varsubsetneq" => [0x0228A, 0x0FE00], "varsubsetneqq" => [0x02ACB, 0x0FE00], "varsupsetneq" => [0x0228B, 0x0FE00], "varsupsetneqq" => [0x02ACC, 0x0FE00], "vartheta" => [0x003D1], "vartriangleleft" => [0x022B2], "vartriangleright" => [0x022B3], "vcy" => [0x00432], "vdash" => [0x022A2], "vee" => [0x02228], "veebar" => [0x022BB], "veeeq" => [0x0225A], "vellip" => [0x022EE], "verbar" => [0x0007C], "vert" => [0x0007C], "vfr" => [0x1D533], "vltri" => [0x022B2], "vnsub" => [0x02282, 0x020D2], "vnsup" => [0x02283, 0x020D2], "vopf" => [0x1D567], "vprop" => [0x0221D], "vrtri" => [0x022B3], "vscr" => [0x1D4CB], "vsubnE" => [0x02ACB, 0x0FE00], "vsubne" => [0x0228A, 0x0FE00], "vsupnE" => [0x02ACC, 0x0FE00], "vsupne" => [0x0228B, 0x0FE00], "vzigzag" => [0x0299A], "wcirc" => [0x00175], "wedbar" => [0x02A5F], "wedge" => [0x02227], "wedgeq" => [0x02259], "weierp" => [0x02118], "wfr" => [0x1D534], "wopf" => [0x1D568], "wp" => [0x02118], "wr" => [0x02240], "wreath" => [0x02240], "wscr" => [0x1D4CC], "xcap" => [0x022C2], "xcirc" => [0x025EF], "xcup" => [0x022C3], "xdtri" => [0x025BD], "xfr" => [0x1D535], "xhArr" => [0x027FA], "xharr" => [0x027F7], "xi" => [0x003BE], "xlArr" => [0x027F8], "xlarr" => [0x027F5], "xmap" => [0x027FC], "xnis" => [0x022FB], "xodot" => [0x02A00], "xopf" => [0x1D569], "xoplus" => [0x02A01], "xotime" => [0x02A02], "xrArr" => [0x027F9], "xrarr" => [0x027F6], "xscr" => [0x1D4CD], "xsqcup" => [0x02A06], "xuplus" => [0x02A04], "xutri" => [0x025B3], "xvee" => [0x022C1], "xwedge" => [0x022C0], "yacute" => [0x000FD], "yacy" => [0x0044F], "ycirc" => [0x00177], "ycy" => [0x0044B], "yen" => [0x000A5], "yfr" => [0x1D536], "yicy" => [0x00457], "yopf" => [0x1D56A], "yscr" => [0x1D4CE], "yucy" => [0x0044E], "yuml" => [0x000FF], "zacute" => [0x0017A], "zcaron" => [0x0017E], "zcy" => [0x00437], "zdot" => [0x0017C], "zeetrf" => [0x02128], "zeta" => [0x003B6], "zfr" => [0x1D537], "zhcy" => [0x00436], "zigrarr" => [0x021DD], "zopf" => [0x1D56B], "zscr" => [0x1D4CF], "zwj" => [0x0200D], "zwnj" => [0x0200C], } PK!9((markdown/literals.rbnu[# coding: UTF-8 # frozen_string_literal: true # :markup: markdown ## #-- # This set of literals is for Ruby 1.9 regular expressions and gives full # unicode support. # # Unlike peg-markdown, this set of literals recognizes Unicode alphanumeric # characters, newlines and spaces. class RDoc::Markdown::Literals # :stopdoc: # This is distinct from setup_parser so that a standalone parser # can redefine #initialize and still have access to the proper # parser setup code. def initialize(str, debug=false) setup_parser(str, debug) end # Prepares for parsing +str+. If you define a custom initialize you must # call this method before #parse def setup_parser(str, debug=false) set_string str, 0 @memoizations = Hash.new { |h,k| h[k] = {} } @result = nil @failed_rule = nil @failing_rule_offset = -1 @line_offsets = nil setup_foreign_grammar end attr_reader :string attr_reader :failing_rule_offset attr_accessor :result, :pos def current_column(target=pos) if string[target] == "\n" && (c = string.rindex("\n", target-1) || -1) return target - c elsif c = string.rindex("\n", target) return target - c end target + 1 end def position_line_offsets unless @position_line_offsets @position_line_offsets = [] total = 0 string.each_line do |line| total += line.size @position_line_offsets << total end end @position_line_offsets end if [].respond_to? :bsearch_index def current_line(target=pos) if line = position_line_offsets.bsearch_index {|x| x > target } return line + 1 end raise "Target position #{target} is outside of string" end else def current_line(target=pos) if line = position_line_offsets.index {|x| x > target } return line + 1 end raise "Target position #{target} is outside of string" end end def current_character(target=pos) if target < 0 || target >= string.size raise "Target position #{target} is outside of string" end string[target, 1] end KpegPosInfo = Struct.new(:pos, :lno, :col, :line, :char) def current_pos_info(target=pos) l = current_line target c = current_column target ln = get_line(l-1) chr = string[target,1] KpegPosInfo.new(target, l, c, ln, chr) end def lines string.lines end def get_line(no) loff = position_line_offsets if no < 0 raise "Line No is out of range: #{no} < 0" elsif no >= loff.size raise "Line No is out of range: #{no} >= #{loff.size}" end lend = loff[no]-1 lstart = no > 0 ? loff[no-1] : 0 string[lstart..lend] end def get_text(start) @string[start..@pos-1] end # Sets the string and current parsing position for the parser. def set_string string, pos @string = string @string_size = string ? string.size : 0 @pos = pos @position_line_offsets = nil end def show_pos width = 10 if @pos < width "#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")" else "#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")" end end def failure_info l = current_line @failing_rule_offset c = current_column @failing_rule_offset if @failed_rule.kind_of? Symbol info = self.class::Rules[@failed_rule] "line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'" else "line #{l}, column #{c}: failed rule '#{@failed_rule}'" end end def failure_caret p = current_pos_info @failing_rule_offset "#{p.line.chomp}\n#{' ' * (p.col - 1)}^" end def failure_character current_character @failing_rule_offset end def failure_oneline p = current_pos_info @failing_rule_offset if @failed_rule.kind_of? Symbol info = self.class::Rules[@failed_rule] "@#{p.lno}:#{p.col} failed rule '#{info.name}', got '#{p.char}'" else "@#{p.lno}:#{p.col} failed rule '#{@failed_rule}', got '#{p.char}'" end end class ParseError < RuntimeError end def raise_error raise ParseError, failure_oneline end def show_error(io=STDOUT) error_pos = @failing_rule_offset p = current_pos_info(error_pos) io.puts "On line #{p.lno}, column #{p.col}:" if @failed_rule.kind_of? Symbol info = self.class::Rules[@failed_rule] io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')" else io.puts "Failed to match rule '#{@failed_rule}'" end io.puts "Got: #{p.char.inspect}" io.puts "=> #{p.line}" io.print(" " * (p.col + 2)) io.puts "^" end def set_failed_rule(name) if @pos > @failing_rule_offset @failed_rule = name @failing_rule_offset = @pos end end attr_reader :failed_rule def match_string(str) len = str.size if @string[pos,len] == str @pos += len return str end return nil end def scan(reg) if m = reg.match(@string, @pos) @pos = m.end(0) return true end return nil end if "".respond_to? :ord def get_byte if @pos >= @string_size return nil end s = @string[@pos].ord @pos += 1 s end else def get_byte if @pos >= @string_size return nil end s = @string[@pos] @pos += 1 s end end def parse(rule=nil) # We invoke the rules indirectly via apply # instead of by just calling them as methods because # if the rules use left recursion, apply needs to # manage that. if !rule apply(:_root) else method = rule.gsub("-","_hyphen_") apply :"_#{method}" end end class MemoEntry def initialize(ans, pos) @ans = ans @pos = pos @result = nil @set = false @left_rec = false end attr_reader :ans, :pos, :result, :set attr_accessor :left_rec def move!(ans, pos, result) @ans = ans @pos = pos @result = result @set = true @left_rec = false end end def external_invoke(other, rule, *args) old_pos = @pos old_string = @string set_string other.string, other.pos begin if val = __send__(rule, *args) other.pos = @pos other.result = @result else other.set_failed_rule "#{self.class}##{rule}" end val ensure set_string old_string, old_pos end end def apply_with_args(rule, *args) @result = nil memo_key = [rule, args] if m = @memoizations[memo_key][@pos] @pos = m.pos if !m.set m.left_rec = true return nil end @result = m.result return m.ans else m = MemoEntry.new(nil, @pos) @memoizations[memo_key][@pos] = m start_pos = @pos ans = __send__ rule, *args lr = m.left_rec m.move! ans, @pos, @result # Don't bother trying to grow the left recursion # if it's failing straight away (thus there is no seed) if ans and lr return grow_lr(rule, args, start_pos, m) else return ans end end end def apply(rule) @result = nil if m = @memoizations[rule][@pos] @pos = m.pos if !m.set m.left_rec = true return nil end @result = m.result return m.ans else m = MemoEntry.new(nil, @pos) @memoizations[rule][@pos] = m start_pos = @pos ans = __send__ rule lr = m.left_rec m.move! ans, @pos, @result # Don't bother trying to grow the left recursion # if it's failing straight away (thus there is no seed) if ans and lr return grow_lr(rule, nil, start_pos, m) else return ans end end end def grow_lr(rule, args, start_pos, m) while true @pos = start_pos @result = m.result if args ans = __send__ rule, *args else ans = __send__ rule end return nil unless ans break if @pos <= m.pos m.move! ans, @pos, @result end @result = m.result @pos = m.pos return m.ans end class RuleInfo def initialize(name, rendered) @name = name @rendered = rendered end attr_reader :name, :rendered end def self.rule_info(name, rendered) RuleInfo.new(name, rendered) end # :startdoc: # :stopdoc: def setup_foreign_grammar; end # Alphanumeric = /\p{Word}/ def _Alphanumeric _tmp = scan(/\G(?-mix:\p{Word})/) set_failed_rule :_Alphanumeric unless _tmp return _tmp end # AlphanumericAscii = /[A-Za-z0-9]/ def _AlphanumericAscii _tmp = scan(/\G(?-mix:[A-Za-z0-9])/) set_failed_rule :_AlphanumericAscii unless _tmp return _tmp end # BOM = "uFEFF" def _BOM _tmp = match_string("uFEFF") set_failed_rule :_BOM unless _tmp return _tmp end # Newline = /\n|\r\n?|\p{Zl}|\p{Zp}/ def _Newline _tmp = scan(/\G(?-mix:\n|\r\n?|\p{Zl}|\p{Zp})/) set_failed_rule :_Newline unless _tmp return _tmp end # NonAlphanumeric = /\p{^Word}/ def _NonAlphanumeric _tmp = scan(/\G(?-mix:\p{^Word})/) set_failed_rule :_NonAlphanumeric unless _tmp return _tmp end # Spacechar = /\t|\p{Zs}/ def _Spacechar _tmp = scan(/\G(?-mix:\t|\p{Zs})/) set_failed_rule :_Spacechar unless _tmp return _tmp end Rules = {} Rules[:_Alphanumeric] = rule_info("Alphanumeric", "/\\p{Word}/") Rules[:_AlphanumericAscii] = rule_info("AlphanumericAscii", "/[A-Za-z0-9]/") Rules[:_BOM] = rule_info("BOM", "\"uFEFF\"") Rules[:_Newline] = rule_info("Newline", "/\\n|\\r\\n?|\\p{Zl}|\\p{Zp}/") Rules[:_NonAlphanumeric] = rule_info("NonAlphanumeric", "/\\p{^Word}/") Rules[:_Spacechar] = rule_info("Spacechar", "/\\t|\\p{Zs}/") # :startdoc: end PK!p-}}alias.rbnu[# 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_accessor :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 ## # Full old name including namespace def full_old_name @full_name || "#{parent.name}#{pretty_old_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 PK!epC0meta_method.rbnu[# frozen_string_literal: true ## # MetaMethod represents a meta-programmed method class RDoc::MetaMethod < RDoc::AnyMethod end PK!Henormal_class.rbnu[# 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 PK!srubygems_hook.rbnu[# frozen_string_literal: true require 'rubygems/user_interaction' require 'fileutils' require_relative '../rdoc' ## # Gem::RDoc provides methods to generate RDoc and ri data for installed gems # upon gem installation. # # This file is automatically required by RubyGems 1.9 and newer. class RDoc::RubygemsHook include Gem::UserInteraction extend Gem::UserInteraction @rdoc_version = nil @specs = [] ## # Force installation of documentation? attr_accessor :force ## # Generate rdoc? attr_accessor :generate_rdoc ## # Generate ri data? attr_accessor :generate_ri class << self ## # Loaded version of RDoc. Set by ::load_rdoc attr_reader :rdoc_version end ## # Post installs hook that generates documentation for each specification in # +specs+ def self.generation_hook installer, specs start = Time.now types = installer.document generate_rdoc = types.include? 'rdoc' generate_ri = types.include? 'ri' specs.each do |spec| new(spec, generate_rdoc, generate_ri).generate end return unless generate_rdoc or generate_ri duration = (Time.now - start).to_i names = specs.map(&:name).join ', ' say "Done installing documentation for #{names} after #{duration} seconds" end ## # Loads the RDoc generator def self.load_rdoc return if @rdoc_version require_relative 'rdoc' @rdoc_version = Gem::Version.new ::RDoc::VERSION end ## # Creates a new documentation generator for +spec+. RDoc and ri data # generation can be enabled or disabled through +generate_rdoc+ and # +generate_ri+ respectively. # # Only +generate_ri+ is enabled by default. def initialize spec, generate_rdoc = false, generate_ri = true @doc_dir = spec.doc_dir @force = false @rdoc = nil @spec = spec @generate_rdoc = generate_rdoc @generate_ri = generate_ri @rdoc_dir = spec.doc_dir 'rdoc' @ri_dir = spec.doc_dir 'ri' end ## # Removes legacy rdoc arguments from +args+ #-- # TODO move to RDoc::Options def delete_legacy_args args args.delete '--inline-source' args.delete '--promiscuous' args.delete '-p' args.delete '--one-file' end ## # Generates documentation using the named +generator+ ("darkfish" or "ri") # and following the given +options+. # # Documentation will be generated into +destination+ def document generator, options, destination generator_name = generator options = options.dup options.exclude ||= [] # TODO maybe move to RDoc::Options#finish options.setup_generator generator options.op_dir = destination Dir.chdir @spec.full_gem_path do options.finish end generator = options.generator.new @rdoc.store, options @rdoc.options = options @rdoc.generator = generator say "Installing #{generator_name} documentation for #{@spec.full_name}" FileUtils.mkdir_p options.op_dir Dir.chdir options.op_dir do begin @rdoc.class.current = @rdoc @rdoc.generator.generate ensure @rdoc.class.current = nil end end end ## # Generates RDoc and ri data def generate return if @spec.default_gem? return unless @generate_ri or @generate_rdoc setup options = nil args = @spec.rdoc_options args.concat @spec.source_paths args.concat @spec.extra_rdoc_files case config_args = Gem.configuration[:rdoc] when String then args = args.concat config_args.split(' ') when Array then args = args.concat config_args end delete_legacy_args args Dir.chdir @spec.full_gem_path do options = ::RDoc::Options.new options.default_title = "#{@spec.full_name} Documentation" options.parse args end options.quiet = !Gem.configuration.really_verbose @rdoc = new_rdoc @rdoc.options = options store = RDoc::Store.new store.encoding = options.encoding store.dry_run = options.dry_run store.main = options.main_page store.title = options.title @rdoc.store = store say "Parsing documentation for #{@spec.full_name}" Dir.chdir @spec.full_gem_path do @rdoc.parse_files options.files end document 'ri', options, @ri_dir if @generate_ri and (@force or not File.exist? @ri_dir) document 'darkfish', options, @rdoc_dir if @generate_rdoc and (@force or not File.exist? @rdoc_dir) end ## # #new_rdoc creates a new RDoc instance. This method is provided only to # make testing easier. def new_rdoc # :nodoc: ::RDoc::RDoc.new end ## # Is rdoc documentation installed? def rdoc_installed? File.exist? @rdoc_dir end ## # Removes generated RDoc and ri data def remove base_dir = @spec.base_dir raise Gem::FilePermissionError, base_dir unless File.writable? base_dir FileUtils.rm_rf @rdoc_dir FileUtils.rm_rf @ri_dir end ## # Is ri data installed? def ri_installed? File.exist? @ri_dir end ## # Prepares the spec for documentation generation def setup self.class.load_rdoc raise Gem::FilePermissionError, @doc_dir if File.exist?(@doc_dir) and not File.writable?(@doc_dir) FileUtils.mkdir_p @doc_dir unless File.exist? @doc_dir end end PK!% s66rdoc.rbnu[# frozen_string_literal: true require_relative '../rdoc' require 'find' require 'fileutils' require 'pathname' require 'time' ## # This is the driver for generating RDoc output. It handles file parsing and # generation of output. # # To use this class to generate RDoc output via the API, the recommended way # is: # # rdoc = RDoc::RDoc.new # options = RDoc::Options.load_options # returns an RDoc::Options instance # # set extra options # rdoc.document options # # You can also generate output like the +rdoc+ executable: # # rdoc = RDoc::RDoc.new # rdoc.document argv # # Where +argv+ is an array of strings, each corresponding to an argument you'd # give rdoc on the command line. See rdoc --help for details. class RDoc::RDoc @current = nil ## # This is the list of supported output generators GENERATORS = {} ## # List of directory names always skipped UNCONDITIONALLY_SKIPPED_DIRECTORIES = %w[CVS .svn .git].freeze ## # List of directory names skipped if test suites should be skipped TEST_SUITE_DIRECTORY_NAMES = %w[spec test].freeze ## # Generator instance used for creating output attr_accessor :generator ## # Hash of files and their last modified times. attr_reader :last_modified ## # RDoc options attr_accessor :options ## # Accessor for statistics. Available after each call to parse_files attr_reader :stats ## # The current documentation store attr_reader :store ## # Add +klass+ that can generate output after parsing def self.add_generator(klass) name = klass.name.sub(/^RDoc::Generator::/, '').downcase GENERATORS[name] = klass end ## # Active RDoc::RDoc instance def self.current @current end ## # Sets the active RDoc::RDoc instance def self.current= rdoc @current = rdoc end ## # Creates a new RDoc::RDoc instance. Call #document to parse files and # generate documentation. def initialize @current = nil @generator = nil @last_modified = {} @old_siginfo = nil @options = nil @stats = nil @store = nil end ## # Report an error message and exit def error(msg) raise RDoc::Error, msg end ## # Gathers a set of parseable files from the files and directories listed in # +files+. def gather_files files files = ["."] if files.empty? file_list = normalized_file_list files, true, @options.exclude file_list = remove_unparseable(file_list) if file_list.count {|name, mtime| file_list[name] = @last_modified[name] unless mtime mtime } > 0 @last_modified.replace file_list file_list.keys.sort else [] end end ## # Turns RDoc from stdin into HTML def handle_pipe @html = RDoc::Markup::ToHtml.new @options parser = RDoc::Text::MARKUP_FORMAT[@options.markup] document = parser.parse $stdin.read out = @html.convert document $stdout.write out end ## # Installs a siginfo handler that prints the current filename. def install_siginfo_handler return unless Signal.list.include? 'INFO' @old_siginfo = trap 'INFO' do puts @current if @current end end ## # Create an output dir if it doesn't exist. If it does exist, but doesn't # contain the flag file created.rid then we refuse to use it, as # we may clobber some manually generated documentation def setup_output_dir(dir, force) flag_file = output_flag_file dir last = {} if @options.dry_run then # do nothing elsif File.exist? dir then error "#{dir} exists and is not a directory" unless File.directory? dir begin File.open flag_file do |io| unless force then Time.parse io.gets io.each do |line| file, time = line.split "\t", 2 time = Time.parse(time) rescue next last[file] = time end end end rescue SystemCallError, TypeError error <<-ERROR Directory #{dir} already exists, but it looks like it isn't an RDoc directory. Because RDoc doesn't want to risk destroying any of your existing files, you'll need to specify a different output directory name (using the --op option) ERROR end unless @options.force_output else FileUtils.mkdir_p dir FileUtils.touch flag_file end last end ## # Sets the current documentation tree to +store+ and sets the store's rdoc # driver to this instance. def store= store @store = store @store.rdoc = self end ## # Update the flag file in an output directory. def update_output_dir(op_dir, time, last = {}) return if @options.dry_run or not @options.update_output_dir unless ENV['SOURCE_DATE_EPOCH'].nil? time = Time.at(ENV['SOURCE_DATE_EPOCH'].to_i).gmtime end File.open output_flag_file(op_dir), "w" do |f| f.puts time.rfc2822 last.each do |n, t| f.puts "#{n}\t#{t.rfc2822}" end end end ## # Return the path name of the flag file in an output directory. def output_flag_file(op_dir) File.join op_dir, "created.rid" end ## # The .document file contains a list of file and directory name patterns, # representing candidates for documentation. It may also contain comments # (starting with '#') def parse_dot_doc_file in_dir, filename # read and strip comments patterns = File.read(filename).gsub(/#.*/, '') result = {} patterns.split(' ').each do |patt| candidates = Dir.glob(File.join(in_dir, patt)) result.update normalized_file_list(candidates, false, @options.exclude) end result end ## # Given a list of files and directories, create a list of all the Ruby # files they contain. # # If +force_doc+ is true we always add the given files, if false, only # add files that we guarantee we can parse. It is true when looking at # files given on the command line, false when recursing through # subdirectories. # # The effect of this is that if you want a file with a non-standard # extension parsed, you must name it explicitly. def normalized_file_list(relative_files, force_doc = false, exclude_pattern = nil) file_list = {} relative_files.each do |rel_file_name| rel_file_name = rel_file_name.sub(/^\.\//, '') next if rel_file_name.end_with? 'created.rid' next if exclude_pattern && exclude_pattern =~ rel_file_name stat = File.stat rel_file_name rescue next case type = stat.ftype when "file" then mtime = (stat.mtime unless (last_modified = @last_modified[rel_file_name] and stat.mtime.to_i <= last_modified.to_i)) if force_doc or RDoc::Parser.can_parse(rel_file_name) then file_list[rel_file_name] = mtime end when "directory" then next if UNCONDITIONALLY_SKIPPED_DIRECTORIES.include?(rel_file_name) basename = File.basename(rel_file_name) next if options.skip_tests && TEST_SUITE_DIRECTORY_NAMES.include?(basename) created_rid = File.join rel_file_name, "created.rid" next if File.file? created_rid dot_doc = File.join rel_file_name, RDoc::DOT_DOC_FILENAME if File.file? dot_doc then file_list.update(parse_dot_doc_file(rel_file_name, dot_doc)) else file_list.update(list_files_in_directory(rel_file_name)) end else warn "rdoc can't parse the #{type} #{rel_file_name}" end end file_list end ## # Return a list of the files to be processed in a directory. We know that # this directory doesn't have a .document file, so we're looking for real # files. However we may well contain subdirectories which must be tested # for .document files. def list_files_in_directory dir files = Dir.glob File.join(dir, "*") normalized_file_list files, false, @options.exclude end ## # Parses +filename+ and returns an RDoc::TopLevel def parse_file filename encoding = @options.encoding filename = filename.encode encoding @stats.add_file filename return if RDoc::Parser.binary? filename content = RDoc::Encoding.read_file filename, encoding return unless content filename_path = Pathname(filename).expand_path begin relative_path = filename_path.relative_path_from @options.root rescue ArgumentError relative_path = filename_path end if @options.page_dir and relative_path.to_s.start_with? @options.page_dir.to_s then relative_path = relative_path.relative_path_from @options.page_dir end top_level = @store.add_file filename, relative_name: relative_path.to_s parser = RDoc::Parser.for top_level, filename, content, @options, @stats return unless parser parser.scan # restart documentation for the classes & modules found top_level.classes_or_modules.each do |cm| cm.done_documenting = false end top_level rescue Errno::EACCES => e $stderr.puts <<-EOF Unable to read #{filename}, #{e.message} Please check the permissions for this file. Perhaps you do not have access to it or perhaps the original author's permissions are to restrictive. If the this is not your library please report a bug to the author. EOF rescue => e $stderr.puts <<-EOF Before reporting this, could you check that the file you're documenting has proper syntax: #{Gem.ruby} -c #{filename} RDoc is not a full Ruby parser and will fail when fed invalid ruby programs. The internal error was: \t(#{e.class}) #{e.message} EOF $stderr.puts e.backtrace.join("\n\t") if $DEBUG_RDOC raise e nil end ## # Parse each file on the command line, recursively entering directories. def parse_files files file_list = gather_files files @stats = RDoc::Stats.new @store, file_list.length, @options.verbosity return [] if file_list.empty? original_options = @options.dup @stats.begin_adding file_info = file_list.map do |filename| @current = filename parse_file filename end.compact @stats.done_adding @options = original_options file_info end ## # Removes file extensions known to be unparseable from +files+ and TAGS # files for emacs and vim. def remove_unparseable files files.reject do |file, *| file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i or (file =~ /tags$/i and File.open(file, 'rb') { |io| io.read(100) =~ /\A(\f\n[^,]+,\d+$|!_TAG_)/ }) end end ## # Generates documentation or a coverage report depending upon the settings # in +options+. # # +options+ can be either an RDoc::Options instance or an array of strings # equivalent to the strings that would be passed on the command line like # %w[-q -o doc -t My\ Doc\ Title]. #document will automatically # call RDoc::Options#finish if an options instance was given. # # For a list of options, see either RDoc::Options or rdoc --help. # # By default, output will be stored in a directory called "doc" below the # current directory, so make sure you're somewhere writable before invoking. def document options self.store = RDoc::Store.new if RDoc::Options === options then @options = options else @options = RDoc::Options.load_options @options.parse options end @options.finish if @options.pipe then handle_pipe exit end unless @options.coverage_report then @last_modified = setup_output_dir @options.op_dir, @options.force_update end @store.encoding = @options.encoding @store.dry_run = @options.dry_run @store.main = @options.main_page @store.title = @options.title @store.path = @options.op_dir @start_time = Time.now @store.load_cache file_info = parse_files @options.files @options.default_title = "RDoc Documentation" @store.complete @options.visibility @stats.coverage_level = @options.coverage_report if @options.coverage_report then puts puts @stats.report.accept RDoc::Markup::ToRdoc.new elsif file_info.empty? then $stderr.puts "\nNo newer files." unless @options.quiet else gen_klass = @options.generator @generator = gen_klass.new @store, @options generate end if @stats and (@options.coverage_report or not @options.quiet) then puts puts @stats.summary.accept RDoc::Markup::ToRdoc.new end exit @stats.fully_documented? if @options.coverage_report end ## # Generates documentation for +file_info+ (from #parse_files) into the # output dir using the generator selected # by the RDoc options def generate if @options.dry_run then # do nothing @generator.generate else Dir.chdir @options.op_dir do unless @options.quiet then $stderr.puts "\nGenerating #{@generator.class.name.sub(/^.*::/, '')} format into #{Dir.pwd}..." end @generator.generate update_output_dir '.', @start_time, @last_modified end end end ## # Removes a siginfo handler and replaces the previous def remove_siginfo_handler return unless Signal.list.key? 'INFO' handler = @old_siginfo || 'DEFAULT' trap 'INFO', handler end end begin require 'rubygems' rdoc_extensions = Gem.find_files 'rdoc/discover' rdoc_extensions.each do |extension| begin load extension rescue => e warn "error loading #{extension.inspect}: #{e.message} (#{e.class})" warn "\t#{e.backtrace.join "\n\t"}" if $DEBUG end end rescue LoadError end # require built-in generators after discovery in case they've been replaced require_relative 'generator/darkfish' require_relative 'generator/ri' require_relative 'generator/pot' PK!8KKcross_reference.rbnu[# 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 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 PK!,lVnormal_module.rbnu[# 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 PK!y encoding.rbnu[# 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 def self.remove_frozen_string_literal string string =~ /\A(?:#!.*\n)?(.*\n)/ first_line = $1 if first_line =~ /\A# +frozen[-_]string[-_]literal[=:].+$/i string = string.sub first_line, '' end string 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 # TODO: Remove this condition after Ruby 2.2 EOL if RUBY_VERSION < '2.3.0' text.force_encoding encoding else String.new text, encoding: encoding end end end end PK!bb]] constant.rbnu[# 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, 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 PK!Lerb_partial.rbnu[# 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 PK! [>  attr.rbnu[# 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 @rw = rw @singleton = singleton 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(self.text, an_alias.new_name, self.rw, self.comment, self.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 = 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 PK!:ܶ parser/rd.rbnu[# frozen_string_literal: true ## # Parse a RD format file. The parsed RDoc::Markup::Document is attached as a # file comment. class RDoc::Parser::RD < RDoc::Parser include RDoc::Parser::Text parse_files_matching(/\.rd(?:\.[^.]+)?$/) ## # Creates an rd-format TopLevel for the given file. def scan comment = RDoc::Comment.new @content, @top_level comment.format = 'rd' @top_level.comment = comment end end PK!T͋͋ parser/c.rbnu[# frozen_string_literal: true require 'tsort' ## # RDoc::Parser::C attempts to parse C extension files. It looks for # the standard patterns that you find in extensions: +rb_define_class+, # +rb_define_method+ and so on. It tries to find the corresponding # C source for the methods and extract comments, but if we fail # we don't worry too much. # # The comments associated with a Ruby method are extracted from the C # comment block associated with the routine that _implements_ that # method, that is to say the method whose name is given in the # +rb_define_method+ call. For example, you might write: # # /* # * Returns a new array that is a one-dimensional flattening of this # * array (recursively). That is, for every element that is an array, # * extract its elements into the new array. # * # * s = [ 1, 2, 3 ] #=> [1, 2, 3] # * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]] # * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10] # * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # */ # static VALUE # rb_ary_flatten(VALUE ary) # { # ary = rb_obj_dup(ary); # rb_ary_flatten_bang(ary); # return ary; # } # # ... # # void # Init_Array(void) # { # ... # rb_define_method(rb_cArray, "flatten", rb_ary_flatten, 0); # # Here RDoc will determine from the +rb_define_method+ line that there's a # method called "flatten" in class Array, and will look for the implementation # in the method +rb_ary_flatten+. It will then use the comment from that # method in the HTML output. This method must be in the same source file # as the +rb_define_method+. # # The comment blocks may include special directives: # # [Document-class: +name+] # Documentation for the named class. # # [Document-module: +name+] # Documentation for the named module. # # [Document-const: +name+] # Documentation for the named +rb_define_const+. # # Constant values can be supplied on the first line of the comment like so: # # /* 300: The highest possible score in bowling */ # rb_define_const(cFoo, "PERFECT", INT2FIX(300)); # # The value can contain internal colons so long as they are escaped with a \ # # [Document-global: +name+] # Documentation for the named +rb_define_global_const+ # # [Document-variable: +name+] # Documentation for the named +rb_define_variable+ # # [Document-method\: +method_name+] # Documentation for the named method. Use this when the method name is # unambiguous. # # [Document-method\: ClassName::method_name] # Documentation for a singleton method in the given class. Use this when # the method name alone is ambiguous. # # [Document-method\: ClassName#method_name] # Documentation for a instance method in the given class. Use this when the # method name alone is ambiguous. # # [Document-attr: +name+] # Documentation for the named attribute. # # [call-seq: text up to an empty line] # Because C source doesn't give descriptive names to Ruby-level parameters, # you need to document the calling sequence explicitly # # In addition, RDoc assumes by default that the C method implementing a # Ruby function is in the same source file as the rb_define_method call. # If this isn't the case, add the comment: # # rb_define_method(....); // in filename # # As an example, we might have an extension that defines multiple classes # in its Init_xxx method. We could document them using # # /* # * Document-class: MyClass # * # * Encapsulate the writing and reading of the configuration # * file. ... # */ # # /* # * Document-method: read_value # * # * call-seq: # * cfg.read_value(key) -> value # * cfg.read_value(key} { |key| } -> value # * # * Return the value corresponding to +key+ from the configuration. # * In the second form, if the key isn't found, invoke the # * block and return its value. # */ class RDoc::Parser::C < RDoc::Parser parse_files_matching(/\.(?:([CcHh])\1?|c([+xp])\2|y)\z/) include RDoc::Text # :stopdoc: BOOL_ARG_PATTERN = /\s*+\b([01]|Q?(?:true|false)|TRUE|FALSE)\b\s*/ TRUE_VALUES = ['1', 'TRUE', 'true', 'Qtrue'].freeze # :startdoc: ## # Maps C variable names to names of Ruby classes or modules attr_reader :classes ## # C file the parser is parsing attr_accessor :content ## # Dependencies from a missing enclosing class to the classes in # missing_dependencies that depend upon it. attr_reader :enclosure_dependencies ## # Maps C variable names to names of Ruby classes (and singleton classes) attr_reader :known_classes ## # Classes found while parsing the C file that were not yet registered due to # a missing enclosing class. These are processed by do_missing attr_reader :missing_dependencies ## # Maps C variable names to names of Ruby singleton classes attr_reader :singleton_classes ## # The TopLevel items in the parsed file belong to attr_reader :top_level ## # Prepares for parsing a C file. See RDoc::Parser#initialize for details on # the arguments. def initialize top_level, file_name, content, options, stats super @known_classes = RDoc::KNOWN_CLASSES.dup @content = handle_tab_width handle_ifdefs_in @content @file_dir = File.dirname @file_name @classes = load_variable_map :c_class_variables @singleton_classes = load_variable_map :c_singleton_class_variables @markup = @options.markup # class_variable => { function => [method, ...] } @methods = Hash.new { |h, f| h[f] = Hash.new { |i, m| i[m] = [] } } # missing variable => [handle_class_module arguments] @missing_dependencies = {} # missing enclosure variable => [dependent handle_class_module arguments] @enclosure_dependencies = Hash.new { |h, k| h[k] = [] } @enclosure_dependencies.instance_variable_set :@missing_dependencies, @missing_dependencies @enclosure_dependencies.extend TSort def @enclosure_dependencies.tsort_each_node &block each_key(&block) rescue TSort::Cyclic => e cycle_vars = e.message.scan(/"(.*?)"/).flatten cycle = cycle_vars.sort.map do |var_name| delete var_name var_name, type, mod_name, = @missing_dependencies[var_name] "#{type} #{mod_name} (#{var_name})" end.join ', ' warn "Unable to create #{cycle} due to a cyclic class or module creation" retry end def @enclosure_dependencies.tsort_each_child node, &block fetch(node, []).each(&block) end end ## # Scans #content for rb_define_alias def do_aliases @content.scan(/rb_define_alias\s*\( \s*(\w+), \s*"(.+?)", \s*"(.+?)" \s*\)/xm) do |var_name, new_name, old_name| class_name = @known_classes[var_name] unless class_name then @options.warn "Enclosing class or module %p for alias %s %s is not known" % [ var_name, new_name, old_name] next end class_obj = find_class var_name, class_name comment = find_alias_comment var_name, new_name, old_name comment.normalize if comment.to_s.empty? and existing_method = class_obj.method_list.find { |m| m.name == old_name} comment = existing_method.comment end add_alias(var_name, class_obj, old_name, new_name, comment) end end ## # Add alias, either from a direct alias definition, or from two # method that reference the same function. def add_alias(var_name, class_obj, old_name, new_name, comment) al = RDoc::Alias.new '', old_name, new_name, '' al.singleton = @singleton_classes.key? var_name al.comment = comment al.record_location @top_level class_obj.add_alias al @stats.add_alias al al end ## # Scans #content for rb_attr and rb_define_attr def do_attrs @content.scan(/rb_attr\s*\( \s*(\w+), \s*([\w"()]+), #{BOOL_ARG_PATTERN}, #{BOOL_ARG_PATTERN}, \s*\w+\);/xmo) do |var_name, attr_name, read, write| handle_attr var_name, attr_name, read, write end @content.scan(%r%rb_define_attr\( \s*([\w\.]+), \s*"([^"]+)", #{BOOL_ARG_PATTERN}, #{BOOL_ARG_PATTERN}\); %xmo) do |var_name, attr_name, read, write| handle_attr var_name, attr_name, read, write end end ## # Scans #content for boot_defclass def do_boot_defclass @content.scan(/(\w+)\s*=\s*boot_defclass\s*\(\s*"(\w+?)",\s*(\w+?)\s*\)/) do |var_name, class_name, parent| parent = nil if parent == "0" handle_class_module(var_name, :class, class_name, parent, nil) end end ## # Scans #content for rb_define_class, boot_defclass, rb_define_class_under # and rb_singleton_class def do_classes_and_modules do_boot_defclass if @file_name == "class.c" @content.scan( %r( (?\s*\(\s*) {0} (?\s*\)\s*) {0} (?\s*"(?\w+)") {0} (?\s*(?: (?[\w\*\s\(\)\.\->]+) | rb_path2class\s*\(\s*"(?[\w:]+)"\s*\) )) {0} (?\w+) {0} (?[\w\.]+)\s* = \s*rb_(?: define_(?: class(?: # rb_define_class(name, parent_name) \(\s* \g, \g \s*\) | _under\g # rb_define_class_under(under, name, parent_name...) \g, \g, \g \g ) | (?) module(?: # rb_define_module(name) \g \g \g | _under\g # rb_define_module_under(under, name) \g, \g \g ) ) | (?(?:\s*"\w+",)*\s*NULL\s*) {0} struct_define(?: \g # rb_struct_define(name, ...) \g, | _under\g # rb_struct_define_under(under, name, ...) \g, \g, | _without_accessor(?: \g # rb_struct_define_without_accessor(name, parent_name, ...) | _under\g # rb_struct_define_without_accessor_under(under, name, parent_name, ...) \g, ) \g, \g, \s*\w+, # Allocation function ) \g \g | singleton_class\g # rb_singleton_class(target_class_name) (?\w+) \g ) )mx ) do if target_class_name = $~[:target_class_name] # rb_singleton_class(target_class_name) handle_singleton $~[:var_name], target_class_name next end var_name = $~[:var_name] type = $~[:module] ? :module : :class class_name = $~[:class_name] parent_name = $~[:parent_name] || $~[:path] under = $~[:under] attributes = $~[:attributes] handle_class_module(var_name, type, class_name, parent_name, under) if attributes and !parent_name # rb_struct_define *not* without_accessor true_flag = 'Qtrue' attributes.scan(/"\K\w+(?=")/) do |attr_name| handle_attr var_name, attr_name, true_flag, true_flag end end end end ## # Scans #content for rb_define_variable, rb_define_readonly_variable, # rb_define_const and rb_define_global_const def do_constants @content.scan(%r%\Wrb_define_ ( variable | readonly_variable | const | global_const ) \s*\( (?:\s*(\w+),)? \s*"(\w+)", \s*(.*?)\s*\)\s*; %xm) do |type, var_name, const_name, definition| var_name = "rb_cObject" if !var_name or var_name == "rb_mKernel" handle_constants type, var_name, const_name, definition end @content.scan(%r% \Wrb_curses_define_const \s*\( \s* (\w+) \s* \) \s*;%xm) do |consts| const = consts.first handle_constants 'const', 'mCurses', const, "UINT2NUM(#{const})" end @content.scan(%r% \Wrb_file_const \s*\( \s* "([^"]+)", \s* (.*?) \s* \) \s*;%xm) do |name, value| handle_constants 'const', 'rb_mFConst', name, value end end ## # Scans #content for rb_include_module def do_includes @content.scan(/rb_include_module\s*\(\s*(\w+?),\s*(\w+?)\s*\)/) do |c,m| next unless cls = @classes[c] m = @known_classes[m] || m comment = new_comment '', @top_level, :c incl = cls.add_include RDoc::Include.new(m, comment) incl.record_location @top_level end end ## # Scans #content for rb_define_method, rb_define_singleton_method, # rb_define_module_function, rb_define_private_method, # rb_define_global_function and define_filetest_function def do_methods @content.scan(%r%rb_define_ ( singleton_method | method | module_function | private_method ) \s*\(\s*([\w\.]+), \s*"([^"]+)", \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\(|\(METHOD\))?(\w+)\)?, \s*(-?\w+)\s*\) (?:;\s*/[*/]\s+in\s+(\w+?\.(?:cpp|c|y)))? %xm) do |type, var_name, meth_name, function, param_count, source_file| # Ignore top-object and weird struct.c dynamic stuff next if var_name == "ruby_top_self" next if var_name == "nstr" var_name = "rb_cObject" if var_name == "rb_mKernel" handle_method(type, var_name, meth_name, function, param_count, source_file) end @content.scan(%r%rb_define_global_function\s*\( \s*"([^"]+)", \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, \s*(-?\w+)\s*\) (?:;\s*/[*/]\s+in\s+(\w+?\.[cy]))? %xm) do |meth_name, function, param_count, source_file| handle_method("method", "rb_mKernel", meth_name, function, param_count, source_file) end @content.scan(/define_filetest_function\s*\( \s*"([^"]+)", \s*(?:RUBY_METHOD_FUNC\(|VALUEFUNC\()?(\w+)\)?, \s*(-?\w+)\s*\)/xm) do |meth_name, function, param_count| handle_method("method", "rb_mFileTest", meth_name, function, param_count) handle_method("singleton_method", "rb_cFile", meth_name, function, param_count) end end ## # Creates classes and module that were missing were defined due to the file # order being different than the declaration order. def do_missing return if @missing_dependencies.empty? @enclosure_dependencies.tsort.each do |in_module| arguments = @missing_dependencies.delete in_module next unless arguments # dependency on existing class handle_class_module(*arguments) end end ## # Finds the comment for an alias on +class_name+ from +new_name+ to # +old_name+ def find_alias_comment class_name, new_name, old_name content =~ %r%((?>/\*.*?\*/\s+)) rb_define_alias\(\s*#{Regexp.escape class_name}\s*, \s*"#{Regexp.escape new_name}"\s*, \s*"#{Regexp.escape old_name}"\s*\);%xm new_comment($1 || '', @top_level, :c) end ## # Finds a comment for rb_define_attr, rb_attr or Document-attr. # # +var_name+ is the C class variable the attribute is defined on. # +attr_name+ is the attribute's name. # # +read+ and +write+ are the read/write flags ('1' or '0'). Either both or # neither must be provided. def find_attr_comment var_name, attr_name, read = nil, write = nil attr_name = Regexp.escape attr_name rw = if read and write then /\s*#{read}\s*,\s*#{write}\s*/xm else /.*?/m end comment = if @content =~ %r%((?>/\*.*?\*/\s+)) rb_define_attr\((?:\s*#{var_name},)?\s* "#{attr_name}"\s*, #{rw}\)\s*;%xm then $1 elsif @content =~ %r%((?>/\*.*?\*/\s+)) rb_attr\(\s*#{var_name}\s*, \s*#{attr_name}\s*, #{rw},.*?\)\s*;%xm then $1 elsif @content =~ %r%(/\*.*?(?:\s*\*\s*)?) Document-attr:\s#{attr_name}\s*?\n ((?>(.|\n)*?\*/))%x then "#{$1}\n#{$2}" else '' end new_comment comment, @top_level, :c end ## # Generate a Ruby-method table def gen_body_table file_content table = {} file_content.scan(%r{ ((?>/\*.*?\*/\s*)?) ((?:(?:\w+)\s+)? (?:intern\s+)?VALUE\s+(\w+) \s*(?:\([^)]*\))(?:[^\);]|$)) | ((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+(\w+)\s+(\w+)) | ^\s*\#\s*define\s+(\w+)\s+(\w+) }xm) do case when $1 table[$3] = [:func_def, $1, $2, $~.offset(2)] if !table[$3] || table[$3][0] != :func_def when $4 table[$6] = [:macro_def, $4, $5, $~.offset(5), $7] if !table[$6] || table[$6][0] == :macro_alias when $8 table[$8] ||= [:macro_alias, $9] end end table end ## # Find the C code corresponding to a Ruby method def find_body class_name, meth_name, meth_obj, file_content, quiet = false if file_content @body_table ||= {} @body_table[file_content] ||= gen_body_table file_content type, *args = @body_table[file_content][meth_name] end case type when :func_def comment = new_comment args[0], @top_level, :c body = args[1] offset, = args[2] comment.remove_private if comment # try to find the whole body body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content # The comment block may have been overridden with a 'Document-method' # block. This happens in the interpreter when multiple methods are # vectored through to the same C method but those methods are logically # distinct (for example Kernel.hash and Kernel.object_id share the same # implementation override_comment = find_override_comment class_name, meth_obj comment = override_comment if override_comment comment.normalize find_modifiers comment, meth_obj if comment #meth_obj.params = params meth_obj.start_collecting_tokens tk = { :line_no => 1, :char_no => 1, :text => body } meth_obj.add_token tk meth_obj.comment = comment meth_obj.line = file_content[0, offset].count("\n") + 1 body when :macro_def comment = new_comment args[0], @top_level, :c body = args[1] offset, = args[2] find_body class_name, args[3], meth_obj, file_content, true comment.normalize find_modifiers comment, meth_obj meth_obj.start_collecting_tokens tk = { :line_no => 1, :char_no => 1, :text => body } meth_obj.add_token tk meth_obj.comment = comment meth_obj.line = file_content[0, offset].count("\n") + 1 body when :macro_alias # with no comment we hope the aliased definition has it and use it's # definition body = find_body(class_name, args[0], meth_obj, file_content, true) return body if body @options.warn "No definition for #{meth_name}" false else # No body, but might still have an override comment comment = find_override_comment class_name, meth_obj if comment then comment.normalize find_modifiers comment, meth_obj meth_obj.comment = comment '' else @options.warn "No definition for #{meth_name}" false end end end ## # Finds a RDoc::NormalClass or RDoc::NormalModule for +raw_name+ def find_class(raw_name, name, base_name = nil) unless @classes[raw_name] if raw_name =~ /^rb_m/ container = @top_level.add_module RDoc::NormalModule, name else container = @top_level.add_class RDoc::NormalClass, name end container.name = base_name if base_name container.record_location @top_level @classes[raw_name] = container end @classes[raw_name] end ## # Look for class or module documentation above Init_+class_name+(void), # in a Document-class +class_name+ (or module) comment or above an # rb_define_class (or module). If a comment is supplied above a matching # Init_ and a rb_define_class the Init_ comment is used. # # /* # * This is a comment for Foo # */ # Init_Foo(void) { # VALUE cFoo = rb_define_class("Foo", rb_cObject); # } # # /* # * Document-class: Foo # * This is a comment for Foo # */ # Init_foo(void) { # VALUE cFoo = rb_define_class("Foo", rb_cObject); # } # # /* # * This is a comment for Foo # */ # VALUE cFoo = rb_define_class("Foo", rb_cObject); def find_class_comment class_name, class_mod comment = nil if @content =~ %r% ((?>/\*.*?\*/\s+)) (static\s+)? void\s+ Init(?:VM)?_(?i:#{class_name})\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xm then comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '') elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*? (?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm then comment = "/*\n#{$1}" elsif @content =~ %r%((?>/\*.*?\*/\s+)) ([\w\.\s]+\s* = \s+)?rb_define_(class|module)[\t (]*?"(#{class_name})"%xm then comment = $1 elsif @content =~ %r%((?>/\*.*?\*/\s+)) ([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm then comment = $1 else comment = '' end comment = new_comment comment, @top_level, :c comment.normalize look_for_directives_in class_mod, comment class_mod.add_comment comment, @top_level end ## # Generate a const table def gen_const_table file_content table = {} @content.scan(%r{ ((?>^\s*/\*.*?\*/\s+)) rb_define_(\w+)\((?:\s*(?:\w+),)?\s* "(\w+)"\s*, .*?\)\s*; | Document-(?:const|global|variable):\s ((?:\w+::)*\w+) \s*?\n((?>.*?\*/)) }mxi) do case when $1 then table[[$2, $3]] = $1 when $4 then table[$4] = "/*\n" + $5 end end table end ## # Finds a comment matching +type+ and +const_name+ either above the # comment or in the matching Document- section. def find_const_comment(type, const_name, class_name = nil) @const_table ||= {} @const_table[@content] ||= gen_const_table @content table = @const_table[@content] comment = table[[type, const_name]] || (class_name && table[class_name + "::" + const_name]) || table[const_name] || '' new_comment comment, @top_level, :c end ## # Handles modifiers in +comment+ and updates +meth_obj+ as appropriate. def find_modifiers comment, meth_obj comment.normalize comment.extract_call_seq meth_obj look_for_directives_in meth_obj, comment end ## # Finds a Document-method override for +meth_obj+ on +class_name+ def find_override_comment class_name, meth_obj name = Regexp.escape meth_obj.name prefix = Regexp.escape meth_obj.name_prefix comment = if @content =~ %r%Document-method: \s+#{class_name}#{prefix}#{name} \s*?\n((?>.*?\*/))%xm then "/*#{$1}" elsif @content =~ %r%Document-method: \s#{name}\s*?\n((?>.*?\*/))%xm then "/*#{$1}" end return unless comment new_comment comment, @top_level, :c end ## # Creates a new RDoc::Attr +attr_name+ on class +var_name+ that is either # +read+, +write+ or both def handle_attr(var_name, attr_name, read, write) rw = '' rw += 'R' if TRUE_VALUES.include?(read) rw += 'W' if TRUE_VALUES.include?(write) class_name = @known_classes[var_name] return unless class_name class_obj = find_class var_name, class_name return unless class_obj comment = find_attr_comment var_name, attr_name comment.normalize name = attr_name.gsub(/rb_intern(?:_const)?\("([^"]+)"\)/, '\1') attr = RDoc::Attr.new '', name, rw, comment attr.record_location @top_level class_obj.add_attribute attr @stats.add_attribute attr end ## # Creates a new RDoc::NormalClass or RDoc::NormalModule based on +type+ # named +class_name+ in +parent+ which was assigned to the C +var_name+. def handle_class_module(var_name, type, class_name, parent, in_module) parent_name = @known_classes[parent] || parent if in_module then enclosure = @classes[in_module] || @store.find_c_enclosure(in_module) if enclosure.nil? and enclosure = @known_classes[in_module] then enc_type = /^rb_m/ =~ in_module ? :module : :class handle_class_module in_module, enc_type, enclosure, nil, nil enclosure = @classes[in_module] end unless enclosure then @enclosure_dependencies[in_module] << var_name @missing_dependencies[var_name] = [var_name, type, class_name, parent, in_module] return end else enclosure = @top_level end if type == :class then full_name = if RDoc::ClassModule === enclosure then enclosure.full_name + "::#{class_name}" else class_name end if @content =~ %r%Document-class:\s+#{full_name}\s*<\s+([:,\w]+)% then parent_name = $1 end cm = enclosure.add_class RDoc::NormalClass, class_name, parent_name else cm = enclosure.add_module RDoc::NormalModule, class_name end cm.record_location enclosure.top_level find_class_comment cm.full_name, cm case cm when RDoc::NormalClass @stats.add_class cm when RDoc::NormalModule @stats.add_module cm end @classes[var_name] = cm @known_classes[var_name] = cm.full_name @store.add_c_enclosure var_name, cm end ## # Adds constants. By providing some_value: at the start of the comment you # can override the C value of the comment to give a friendly definition. # # /* 300: The perfect score in bowling */ # rb_define_const(cFoo, "PERFECT", INT2FIX(300)); # # Will override INT2FIX(300) with the value +300+ in the output # RDoc. Values may include quotes and escaped colons (\:). def handle_constants(type, var_name, const_name, definition) class_name = @known_classes[var_name] return unless class_name class_obj = find_class var_name, class_name, class_name[/::\K[^:]+\z/] unless class_obj then @options.warn 'Enclosing class or module %p is not known' % [const_name] return end comment = find_const_comment type, const_name, class_name comment.normalize # In the case of rb_define_const, the definition and comment are in # "/* definition: comment */" form. The literal ':' and '\' characters # can be escaped with a backslash. if type.downcase == 'const' then no_match, new_definition, new_comment = comment.text.split(/(\A.*):/) if no_match and no_match.empty? then if new_definition.empty? then # Default to literal C definition new_definition = definition else new_definition = new_definition.gsub("\:", ":") new_definition = new_definition.gsub("\\", '\\') end new_definition.sub!(/\A(\s+)/, '') new_comment = "#{$1}#{new_comment.lstrip}" new_comment = self.new_comment(new_comment, @top_level, :c) con = RDoc::Constant.new const_name, new_definition, new_comment else con = RDoc::Constant.new const_name, definition, comment end else con = RDoc::Constant.new const_name, definition, comment end con.record_location @top_level @stats.add_constant con class_obj.add_constant con end ## # Removes #ifdefs that would otherwise confuse us def handle_ifdefs_in(body) body.gsub(/^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m, '\1') end ## # Adds an RDoc::AnyMethod +meth_name+ defined on a class or module assigned # to +var_name+. +type+ is the type of method definition function used. # +singleton_method+ and +module_function+ create a singleton method. def handle_method(type, var_name, meth_name, function, param_count, source_file = nil) class_name = @known_classes[var_name] singleton = @singleton_classes.key? var_name @methods[var_name][function] << meth_name return unless class_name class_obj = find_class var_name, class_name if existing_method = class_obj.method_list.find { |m| m.c_function == function } add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment) end if class_obj then if meth_name == 'initialize' then meth_name = 'new' singleton = true type = 'method' # force public end meth_obj = RDoc::AnyMethod.new '', meth_name meth_obj.c_function = function meth_obj.singleton = singleton || %w[singleton_method module_function].include?(type) p_count = Integer(param_count) rescue -1 if source_file then file_name = File.join @file_dir, source_file if File.exist? file_name then file_content = File.read file_name else @options.warn "unknown source #{source_file} for #{meth_name} in #{@file_name}" end else file_content = @content end body = find_body class_name, function, meth_obj, file_content if body and meth_obj.document_self then meth_obj.params = if p_count < -1 then # -2 is Array '(*args)' elsif p_count == -1 then # argc, argv rb_scan_args body else args = (1..p_count).map { |i| "p#{i}" } "(#{args.join ', '})" end meth_obj.record_location @top_level if meth_obj.section_title class_obj.temporary_section = class_obj.add_section(meth_obj.section_title) end class_obj.add_method meth_obj @stats.add_method meth_obj meth_obj.visibility = :private if 'private_method' == type end end end ## # Registers a singleton class +sclass_var+ as a singleton of +class_var+ def handle_singleton sclass_var, class_var class_name = @known_classes[class_var] @known_classes[sclass_var] = class_name @singleton_classes[sclass_var] = class_name end ## # Loads the variable map with the given +name+ from the RDoc::Store, if # present. def load_variable_map map_name return {} unless files = @store.cache[map_name] return {} unless name_map = files[@file_name] class_map = {} name_map.each do |variable, name| next unless mod = @store.find_class_or_module(name) class_map[variable] = if map_name == :c_class_variables then mod else name end @known_classes[variable] = name end class_map end ## # Look for directives in a normal comment block: # # /* # * :title: My Awesome Project # */ # # This method modifies the +comment+ def look_for_directives_in context, comment @preprocess.handle comment, context do |directive, param| case directive when 'main' then @options.main_page = param '' when 'title' then @options.default_title = param if @options.respond_to? :default_title= '' end end comment end ## # Extracts parameters from the +method_body+ and returns a method # parameter string. Follows 1.9.3dev's scan-arg-spec, see README.EXT def rb_scan_args method_body method_body =~ /rb_scan_args\((.*?)\)/m return '(*args)' unless $1 $1.split(/,/)[2] =~ /"(.*?)"/ # format argument format = $1.split(//) lead = opt = trail = 0 if format.first =~ /\d/ then lead = $&.to_i format.shift if format.first =~ /\d/ then opt = $&.to_i format.shift if format.first =~ /\d/ then trail = $&.to_i format.shift block_arg = true end end end if format.first == '*' and not block_arg then var = true format.shift if format.first =~ /\d/ then trail = $&.to_i format.shift end end if format.first == ':' then hash = true format.shift end if format.first == '&' then block = true format.shift end # if the format string is not empty there's a bug in the C code, ignore it args = [] position = 1 (1...(position + lead)).each do |index| args << "p#{index}" end position += lead (position...(position + opt)).each do |index| args << "p#{index} = v#{index}" end position += opt if var then args << '*args' position += 1 end (position...(position + trail)).each do |index| args << "p#{index}" end position += trail if hash then args << "p#{position} = {}" end args << '&block' if block "(#{args.join ', '})" end ## # Removes lines that are commented out that might otherwise get picked up # when scanning for classes and methods def remove_commented_out_lines @content = @content.gsub(%r%//.*rb_define_%, '//') end ## # Extracts the classes, modules, methods, attributes, constants and aliases # from a C file and returns an RDoc::TopLevel for this file def scan remove_commented_out_lines do_classes_and_modules do_missing do_constants do_methods do_includes do_aliases do_attrs @store.add_c_variables self @top_level end def new_comment text = nil, location = nil, language = nil RDoc::Comment.new(text, location, language).tap do |comment| comment.format = @markup end end end PK!733parser/text.rbnu[# frozen_string_literal: true ## # Indicates this parser is text and doesn't contain code constructs. # # Include this module in a RDoc::Parser subclass to make it show up as a file, # not as part of a class or module. #-- # This is not named File to avoid overriding ::File module RDoc::Parser::Text end PK! />>parser/ripper_state_lex.rbnu[# frozen_string_literal: true require 'ripper' class RDoc::Parser::RipperStateLex # TODO: Remove this constants after Ruby 2.4 EOL RIPPER_HAS_LEX_STATE = Ripper::Filter.method_defined?(:state) Token = Struct.new(:line_no, :char_no, :kind, :text, :state) EXPR_NONE = 0 EXPR_BEG = 1 EXPR_END = 2 EXPR_ENDARG = 4 EXPR_ENDFN = 8 EXPR_ARG = 16 EXPR_CMDARG = 32 EXPR_MID = 64 EXPR_FNAME = 128 EXPR_DOT = 256 EXPR_CLASS = 512 EXPR_LABEL = 1024 EXPR_LABELED = 2048 EXPR_FITEM = 4096 EXPR_VALUE = EXPR_BEG EXPR_BEG_ANY = (EXPR_BEG | EXPR_MID | EXPR_CLASS) EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG) EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN) class InnerStateLex < Ripper::Filter attr_accessor :lex_state def initialize(code) @lex_state = EXPR_BEG @in_fname = false @continue = false reset super(code) end def reset @command_start = false @cmd_state = @command_start end def on_nl(tok, data) case @lex_state when EXPR_FNAME, EXPR_DOT @continue = true else @continue = false @lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0 end data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_ignored_nl(tok, data) case @lex_state when EXPR_FNAME, EXPR_DOT @continue = true else @continue = false @lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0 end data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_op(tok, data) case tok when '&', '|', '!', '!=', '!~' case @lex_state when EXPR_FNAME, EXPR_DOT @lex_state = EXPR_ARG else @lex_state = EXPR_BEG end when '<<' # TODO next token? case @lex_state when EXPR_FNAME, EXPR_DOT @lex_state = EXPR_ARG else @lex_state = EXPR_BEG end when '?' @lex_state = EXPR_BEG when '&&', '||', '+=', '-=', '*=', '**=', '&=', '|=', '^=', '<<=', '>>=', '||=', '&&=' @lex_state = EXPR_BEG when '::' case @lex_state when EXPR_ARG, EXPR_CMDARG @lex_state = EXPR_DOT when EXPR_FNAME, EXPR_DOT @lex_state = EXPR_ARG else @lex_state = EXPR_BEG end else case @lex_state when EXPR_FNAME, EXPR_DOT @lex_state = EXPR_ARG else @lex_state = EXPR_BEG end end data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_kw(tok, data) case tok when 'class' @lex_state = EXPR_CLASS @in_fname = true when 'def' @lex_state = EXPR_FNAME @continue = true @in_fname = true when 'if', 'unless', 'while', 'until' if ((EXPR_MID | EXPR_END | EXPR_ENDARG | EXPR_ENDFN | EXPR_ARG | EXPR_CMDARG) & @lex_state) != 0 # postfix if @lex_state = EXPR_BEG | EXPR_LABEL else @lex_state = EXPR_BEG end when 'begin', 'case', 'when' @lex_state = EXPR_BEG when 'return', 'break' @lex_state = EXPR_MID else if @lex_state == EXPR_FNAME @lex_state = EXPR_END else @lex_state = EXPR_END end end data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_tstring_beg(tok, data) @lex_state = EXPR_BEG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_tstring_end(tok, data) @lex_state = EXPR_END | EXPR_ENDARG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_CHAR(tok, data) @lex_state = EXPR_END data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_period(tok, data) @lex_state = EXPR_DOT data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_int(tok, data) @lex_state = EXPR_END | EXPR_ENDARG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_float(tok, data) @lex_state = EXPR_END | EXPR_ENDARG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_rational(tok, data) @lex_state = EXPR_END | EXPR_ENDARG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_imaginary(tok, data) @lex_state = EXPR_END | EXPR_ENDARG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_symbeg(tok, data) @lex_state = EXPR_FNAME @continue = true @in_fname = true data << Token.new(lineno, column, __method__, tok, @lex_state) end private def on_variables(event, tok, data) if @in_fname @lex_state = EXPR_ENDFN @in_fname = false @continue = false elsif @continue case @lex_state when EXPR_DOT @lex_state = EXPR_ARG else @lex_state = EXPR_ENDFN @continue = false end else @lex_state = EXPR_CMDARG end data << Token.new(lineno, column, event, tok, @lex_state) end def on_ident(tok, data) on_variables(__method__, tok, data) end def on_ivar(tok, data) @lex_state = EXPR_END on_variables(__method__, tok, data) end def on_cvar(tok, data) @lex_state = EXPR_END on_variables(__method__, tok, data) end def on_gvar(tok, data) @lex_state = EXPR_END on_variables(__method__, tok, data) end def on_backref(tok, data) @lex_state = EXPR_END on_variables(__method__, tok, data) end def on_lparen(tok, data) @lex_state = EXPR_LABEL | EXPR_BEG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_rparen(tok, data) @lex_state = EXPR_ENDFN data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_lbrace(tok, data) @lex_state = EXPR_LABEL | EXPR_BEG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_rbrace(tok, data) @lex_state = EXPR_ENDARG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_lbracket(tok, data) @lex_state = EXPR_LABEL | EXPR_BEG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_rbracket(tok, data) @lex_state = EXPR_ENDARG data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_const(tok, data) case @lex_state when EXPR_FNAME @lex_state = EXPR_ENDFN when EXPR_CLASS, EXPR_CMDARG, EXPR_MID @lex_state = EXPR_ARG else @lex_state = EXPR_CMDARG end data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_sp(tok, data) data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_comma(tok, data) @lex_state = EXPR_BEG | EXPR_LABEL if (EXPR_ARG_ANY & @lex_state) != 0 data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_comment(tok, data) @lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0 data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_ignored_sp(tok, data) @lex_state = EXPR_BEG unless (EXPR_LABEL & @lex_state) != 0 data << Token.new(lineno, column, __method__, tok, @lex_state) end def on_heredoc_beg(tok, data) data << Token.new(lineno, column, __method__, tok, @lex_state) @lex_state = EXPR_END data end def on_heredoc_end(tok, data) data << Token.new(lineno, column, __method__, tok, @lex_state) @lex_state = EXPR_BEG data end def on_default(event, tok, data) reset data << Token.new(lineno, column, event, tok, @lex_state) end end unless RIPPER_HAS_LEX_STATE class InnerStateLex < Ripper::Filter def initialize(code) super(code) end def on_default(event, tok, data) data << Token.new(lineno, column, event, tok, state) end end if RIPPER_HAS_LEX_STATE def get_squashed_tk if @buf.empty? tk = @tokens.shift else tk = @buf.shift end return nil if tk.nil? case tk[:kind] when :on_symbeg then tk = get_symbol_tk(tk) when :on_tstring_beg then tk = get_string_tk(tk) when :on_backtick then if (tk[:state] & (EXPR_FNAME | EXPR_ENDFN)) != 0 @inner_lex.lex_state = EXPR_ARG unless RIPPER_HAS_LEX_STATE tk[:kind] = :on_ident tk[:state] = Ripper::Lexer.const_defined?(:State) ? Ripper::Lexer::State.new(EXPR_ARG) : EXPR_ARG else tk = get_string_tk(tk) end when :on_regexp_beg then tk = get_regexp_tk(tk) when :on_embdoc_beg then tk = get_embdoc_tk(tk) when :on_heredoc_beg then @heredoc_queue << retrieve_heredoc_info(tk) @inner_lex.lex_state = EXPR_END unless RIPPER_HAS_LEX_STATE when :on_nl, :on_ignored_nl, :on_comment, :on_heredoc_end then if !@heredoc_queue.empty? get_heredoc_tk(*@heredoc_queue.shift) elsif tk[:text].nil? # :on_ignored_nl sometimes gives nil tk[:text] = '' end when :on_words_beg then tk = get_words_tk(tk) when :on_qwords_beg then tk = get_words_tk(tk) when :on_symbols_beg then tk = get_words_tk(tk) when :on_qsymbols_beg then tk = get_words_tk(tk) when :on_op then if '&.' == tk[:text] tk[:kind] = :on_period else tk = get_op_tk(tk) end end tk end private def get_symbol_tk(tk) is_symbol = true symbol_tk = Token.new(tk.line_no, tk.char_no, :on_symbol) if ":'" == tk[:text] or ':"' == tk[:text] tk1 = get_string_tk(tk) symbol_tk[:text] = tk1[:text] symbol_tk[:state] = tk1[:state] else case (tk1 = get_squashed_tk)[:kind] when :on_ident symbol_tk[:text] = ":#{tk1[:text]}" symbol_tk[:state] = tk1[:state] when :on_tstring_content symbol_tk[:text] = ":#{tk1[:text]}" symbol_tk[:state] = get_squashed_tk[:state] # skip :on_tstring_end when :on_tstring_end symbol_tk[:text] = ":#{tk1[:text]}" symbol_tk[:state] = tk1[:state] when :on_op symbol_tk[:text] = ":#{tk1[:text]}" symbol_tk[:state] = tk1[:state] when :on_ivar symbol_tk[:text] = ":#{tk1[:text]}" symbol_tk[:state] = tk1[:state] when :on_cvar symbol_tk[:text] = ":#{tk1[:text]}" symbol_tk[:state] = tk1[:state] when :on_gvar symbol_tk[:text] = ":#{tk1[:text]}" symbol_tk[:state] = tk1[:state] when :on_const symbol_tk[:text] = ":#{tk1[:text]}" symbol_tk[:state] = tk1[:state] when :on_kw symbol_tk[:text] = ":#{tk1[:text]}" symbol_tk[:state] = tk1[:state] else is_symbol = false tk = tk1 end end if is_symbol tk = symbol_tk end tk end private def get_string_tk(tk) string = tk[:text] state = nil kind = :on_tstring loop do inner_str_tk = get_squashed_tk if inner_str_tk.nil? break elsif :on_tstring_end == inner_str_tk[:kind] string = string + inner_str_tk[:text] state = inner_str_tk[:state] break elsif :on_label_end == inner_str_tk[:kind] string = string + inner_str_tk[:text] state = inner_str_tk[:state] kind = :on_symbol break else string = string + inner_str_tk[:text] if :on_embexpr_beg == inner_str_tk[:kind] then kind = :on_dstring if :on_tstring == kind end end end Token.new(tk.line_no, tk.char_no, kind, string, state) end private def get_regexp_tk(tk) string = tk[:text] state = nil loop do inner_str_tk = get_squashed_tk if inner_str_tk.nil? break elsif :on_regexp_end == inner_str_tk[:kind] string = string + inner_str_tk[:text] state = inner_str_tk[:state] break else string = string + inner_str_tk[:text] end end Token.new(tk.line_no, tk.char_no, :on_regexp, string, state) end private def get_embdoc_tk(tk) string = tk[:text] until :on_embdoc_end == (embdoc_tk = get_squashed_tk)[:kind] do string = string + embdoc_tk[:text] end string = string + embdoc_tk[:text] Token.new(tk.line_no, tk.char_no, :on_embdoc, string, embdoc_tk.state) end private def get_heredoc_tk(heredoc_name, indent) string = '' start_tk = nil prev_tk = nil until heredoc_end?(heredoc_name, indent, tk = @tokens.shift) do start_tk = tk unless start_tk if (prev_tk.nil? or "\n" == prev_tk[:text][-1]) and 0 != tk[:char_no] string = string + (' ' * tk[:char_no]) end string = string + tk[:text] prev_tk = tk end start_tk = tk unless start_tk prev_tk = tk unless prev_tk @buf.unshift tk # closing heredoc heredoc_tk = Token.new(start_tk.line_no, start_tk.char_no, :on_heredoc, string, prev_tk.state) @buf.unshift heredoc_tk end private def retrieve_heredoc_info(tk) name = tk[:text].gsub(/\A<<[-~]?(['"`]?)(.+)\1\z/, '\2') indent = tk[:text] =~ /\A<<[-~]/ [name, indent] end private def heredoc_end?(name, indent, tk) result = false if :on_heredoc_end == tk[:kind] then tk_name = tk[:text].chomp tk_name.lstrip! if indent if name == tk_name result = true end end result end private def get_words_tk(tk) string = '' start_token = tk[:text] start_quote = tk[:text].rstrip[-1] line_no = tk[:line_no] char_no = tk[:char_no] state = tk[:state] end_quote = case start_quote when ?( then ?) when ?[ then ?] when ?{ then ?} when ?< then ?> else start_quote end end_token = nil loop do tk = get_squashed_tk if tk.nil? end_token = end_quote break elsif :on_tstring_content == tk[:kind] then string += tk[:text] elsif :on_words_sep == tk[:kind] or :on_tstring_end == tk[:kind] then if end_quote == tk[:text].strip then end_token = tk[:text] break else string += tk[:text] end else string += tk[:text] end end text = "#{start_token}#{string}#{end_token}" Token.new(line_no, char_no, :on_dstring, text, state) end private def get_op_tk(tk) redefinable_operators = %w[! != !~ % & * ** + +@ - -@ / < << <= <=> == === =~ > >= >> [] []= ^ ` | ~] if redefinable_operators.include?(tk[:text]) and tk[:state] == EXPR_ARG then @inner_lex.lex_state = EXPR_ARG unless RIPPER_HAS_LEX_STATE tk[:state] = Ripper::Lexer.const_defined?(:State) ? Ripper::Lexer::State.new(EXPR_ARG) : EXPR_ARG tk[:kind] = :on_ident elsif tk[:text] =~ /^[-+]$/ then tk_ahead = get_squashed_tk case tk_ahead[:kind] when :on_int, :on_float, :on_rational, :on_imaginary then tk[:text] += tk_ahead[:text] tk[:kind] = tk_ahead[:kind] tk[:state] = tk_ahead[:state] when :on_heredoc_beg, :on_tstring, :on_dstring # frozen/non-frozen string literal tk[:text] += tk_ahead[:text] tk[:kind] = tk_ahead[:kind] tk[:state] = tk_ahead[:state] else @buf.unshift tk_ahead end end tk end def initialize(code) @buf = [] @heredoc_queue = [] @inner_lex = InnerStateLex.new(code) @tokens = @inner_lex.parse([]) end def self.parse(code) lex = self.new(code) tokens = [] begin while tk = lex.get_squashed_tk tokens.push tk end rescue StopIteration end tokens end def self.end?(token) (token[:state] & EXPR_END) end end PK!Uparser/simple.rbnu[# frozen_string_literal: true ## # Parse a non-source file. We basically take the whole thing as one big # comment. class RDoc::Parser::Simple < RDoc::Parser include RDoc::Parser::Text parse_files_matching(//) attr_reader :content # :nodoc: ## # Prepare to parse a plain file def initialize(top_level, file_name, content, options, stats) super preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include @content = preprocess.handle @content, @top_level end ## # Extract the file contents and attach them to the TopLevel as a comment def scan comment = remove_coding_comment @content comment = remove_private_comment comment comment = RDoc::Comment.new comment, @top_level @top_level.comment = comment @top_level end ## # Removes the encoding magic comment from +text+ def remove_coding_comment text text.sub(/\A# .*coding[=:].*$/, '') end ## # Removes private comments. # # Unlike RDoc::Comment#remove_private this implementation only looks for two # dashes at the beginning of the line. Three or more dashes are considered # to be a rule and ignored. def remove_private_comment comment # Workaround for gsub encoding for Ruby 1.9.2 and earlier empty = '' empty = RDoc::Encoding.change_encoding empty, comment.encoding comment = comment.gsub(%r%^--\n.*?^\+\+\n?%m, empty) comment.sub(%r%^--\n.*%m, empty) end end PK!4QՆ parser/ruby_tools.rbnu[# frozen_string_literal: true ## # Collection of methods for writing parsers module RDoc::Parser::RubyTools ## # Adds a token listener +obj+, but you should probably use token_listener def add_token_listener(obj) @token_listeners ||= [] @token_listeners << obj end ## # Fetches the next token from the scanner def get_tk tk = nil if @tokens.empty? then if @scanner_point >= @scanner.size return nil else tk = @scanner[@scanner_point] @scanner_point += 1 @read.push tk[:text] end else @read.push @unget_read.shift tk = @tokens.shift end if tk == nil || :on___end__ == tk[:kind] tk = nil end return nil unless tk # inform any listeners of our shiny new token @token_listeners.each do |obj| obj.add_token(tk) end if @token_listeners tk end ## # Reads and returns all tokens up to one of +tokens+. Leaves the matched # token in the token list. def get_tk_until(*tokens) read = [] loop do tk = get_tk case tk when *tokens then unget_tk tk break end read << tk end read end ## # Retrieves a String representation of the read tokens def get_tkread read = @read.join("") @read = [] read end ## # Peek equivalent for get_tkread def peek_read @read.join('') end ## # Peek at the next token, but don't remove it from the stream def peek_tk unget_tk(tk = get_tk) tk end ## # Removes the token listener +obj+ def remove_token_listener(obj) @token_listeners.delete(obj) end ## # Resets the tools def reset @read = [] @tokens = [] @unget_read = [] @nest = 0 @scanner_point = 0 end ## # Skips whitespace tokens including newlines def skip_tkspace tokens = [] while (tk = get_tk) and (:on_sp == tk[:kind] or :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind]) do tokens.push(tk) end unget_tk(tk) tokens end ## # Skips whitespace tokens excluding newlines def skip_tkspace_without_nl tokens = [] while (tk = get_tk) and :on_sp == tk[:kind] do tokens.push(tk) end unget_tk(tk) tokens end ## # Has +obj+ listen to tokens def token_listener(obj) add_token_listener obj yield ensure remove_token_listener obj end ## # Returns +tk+ to the scanner def unget_tk(tk) @tokens.unshift tk @unget_read.unshift @read.pop # Remove this token from any listeners @token_listeners.each do |obj| obj.pop_token end if @token_listeners nil end end PK!_Aparser/markdown.rbnu[# frozen_string_literal: true ## # Parse a Markdown format file. The parsed RDoc::Markup::Document is attached # as a file comment. class RDoc::Parser::Markdown < RDoc::Parser include RDoc::Parser::Text parse_files_matching(/\.(md|markdown)(?:\.[^.]+)?$/) ## # Creates an Markdown-format TopLevel for the given file. def scan comment = RDoc::Comment.new @content, @top_level comment.format = 'markdown' @top_level.comment = comment end end PK!5nnparser/ruby.rbnu[# frozen_string_literal: true ## # This file contains stuff stolen outright from: # # rtags.rb - # ruby-lex.rb - ruby lexcal analyzer # ruby-token.rb - ruby tokens # by Keiju ISHITSUKA (Nippon Rational Inc.) # ## # Extracts code elements from a source file returning a TopLevel object # containing the constituent file elements. # # This file is based on rtags # # RubyParser understands how to document: # * classes # * modules # * methods # * constants # * aliases # * private, public, protected # * private_class_function, public_class_function # * private_constant, public_constant # * module_function # * attr, attr_reader, attr_writer, attr_accessor # * extra accessors given on the command line # * metaprogrammed methods # * require # * include # # == Method Arguments # #-- # NOTE: I don't think this works, needs tests, remove the paragraph following # this block when known to work # # The parser extracts the arguments from the method definition. You can # override this with a custom argument definition using the :args: directive: # # ## # # This method tries over and over until it is tired # # def go_go_go(thing_to_try, tries = 10) # :args: thing_to_try # puts thing_to_try # go_go_go thing_to_try, tries - 1 # end # # If you have a more-complex set of overrides you can use the :call-seq: # directive: #++ # # The parser extracts the arguments from the method definition. You can # override this with a custom argument definition using the :call-seq: # directive: # # ## # # This method can be called with a range or an offset and length # # # # :call-seq: # # my_method(Range) # # my_method(offset, length) # # def my_method(*args) # end # # The parser extracts +yield+ expressions from method bodies to gather the # yielded argument names. If your method manually calls a block instead of # yielding or you want to override the discovered argument names use # the :yields: directive: # # ## # # My method is awesome # # def my_method(&block) # :yields: happy, times # block.call 1, 2 # end # # == Metaprogrammed Methods # # To pick up a metaprogrammed method, the parser looks for a comment starting # with '##' before an identifier: # # ## # # This is a meta-programmed method! # # add_my_method :meta_method, :arg1, :arg2 # # The parser looks at the token after the identifier to determine the name, in # this example, :meta_method. If a name cannot be found, a warning is printed # and 'unknown is used. # # You can force the name of a method using the :method: directive: # # ## # # :method: some_method! # # By default, meta-methods are instance methods. To indicate that a method is # a singleton method instead use the :singleton-method: directive: # # ## # # :singleton-method: # # You can also use the :singleton-method: directive with a name: # # ## # # :singleton-method: some_method! # # You can define arguments for metaprogrammed methods via either the # :call-seq:, :arg: or :args: directives. # # Additionally you can mark a method as an attribute by # using :attr:, :attr_reader:, :attr_writer: or :attr_accessor:. Just like # for :method:, the name is optional. # # ## # # :attr_reader: my_attr_name # # == Hidden methods and attributes # # You can provide documentation for methods that don't appear using # the :method:, :singleton-method: and :attr: directives: # # ## # # :attr_writer: ghost_writer # # There is an attribute here, but you can't see it! # # ## # # :method: ghost_method # # There is a method here, but you can't see it! # # ## # # this is a comment for a regular method # # def regular_method() end # # Note that by default, the :method: directive will be ignored if there is a # standard rdocable item following it. require 'ripper' require_relative 'ripper_state_lex' class RDoc::Parser::Ruby < RDoc::Parser parse_files_matching(/\.rbw?$/) include RDoc::TokenStream include RDoc::Parser::RubyTools ## # RDoc::NormalClass type NORMAL = "::" ## # RDoc::SingleClass type SINGLE = "<<" ## # Creates a new Ruby parser. def initialize(top_level, file_name, content, options, stats) super content = handle_tab_width(content) @size = 0 @token_listeners = nil content = RDoc::Encoding.remove_magic_comment content @scanner = RDoc::Parser::RipperStateLex.parse(content) @content = content @scanner_point = 0 @prev_seek = nil @markup = @options.markup @track_visibility = :nodoc != @options.visibility @encoding = @options.encoding reset end def tk_nl?(tk) :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind] end ## # Retrieves the read token stream and replaces +pattern+ with +replacement+ # using gsub. If the result is only a ";" returns an empty string. def get_tkread_clean pattern, replacement # :nodoc: read = get_tkread.gsub(pattern, replacement).strip return '' if read == ';' read end ## # Extracts the visibility information for the visibility token +tk+ # and +single+ class type identifier. # # Returns the visibility type (a string), the visibility (a symbol) and # +singleton+ if the methods following should be converted to singleton # methods. def get_visibility_information tk, single # :nodoc: vis_type = tk[:text] singleton = single == SINGLE vis = case vis_type when 'private' then :private when 'protected' then :protected when 'public' then :public when 'private_class_method' then singleton = true :private when 'public_class_method' then singleton = true :public when 'module_function' then singleton = true :public else raise RDoc::Error, "Invalid visibility: #{tk.name}" end return vis_type, vis, singleton end ## # Look for the first comment in a file that isn't a shebang line. def collect_first_comment skip_tkspace comment = ''.dup comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding first_line = true first_comment_tk_kind = nil line_no = nil tk = get_tk while tk && (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) comment_body = retrieve_comment_body(tk) if first_line and comment_body =~ /\A#!/ then skip_tkspace tk = get_tk elsif first_line and comment_body =~ /\A#\s*-\*-/ then first_line = false skip_tkspace tk = get_tk else break if first_comment_tk_kind and not first_comment_tk_kind === tk[:kind] first_comment_tk_kind = tk[:kind] line_no = tk[:line_no] if first_line first_line = false comment << comment_body tk = get_tk if :on_nl === tk then skip_tkspace_without_nl tk = get_tk end end end unget_tk tk new_comment comment, line_no end ## # Consumes trailing whitespace from the token stream def consume_trailing_spaces # :nodoc: skip_tkspace_without_nl end ## # Creates a new attribute in +container+ with +name+. def create_attr container, single, name, rw, comment # :nodoc: att = RDoc::Attr.new get_tkread, name, rw, comment, single == SINGLE record_location att container.add_attribute att @stats.add_attribute att att end ## # Creates a module alias in +container+ at +rhs_name+ (or at the top-level # for "::") with the name from +constant+. def create_module_alias container, constant, rhs_name # :nodoc: mod = if rhs_name =~ /^::/ then @store.find_class_or_module rhs_name else container.find_module_named rhs_name end container.add_module_alias mod, rhs_name, constant, @top_level end ## # Aborts with +msg+ def error(msg) msg = make_message msg abort msg end ## # Looks for a true or false token. def get_bool skip_tkspace tk = get_tk if :on_kw == tk[:kind] && 'true' == tk[:text] true elsif :on_kw == tk[:kind] && ('false' == tk[:text] || 'nil' == tk[:text]) false else unget_tk tk true end end ## # Look for the name of a class of module (optionally with a leading :: or # with :: separated named) and return the ultimate name, the associated # container, and the given name (with the ::). def get_class_or_module container, ignore_constants = false skip_tkspace name_t = get_tk given_name = ''.dup # class ::A -> A is in the top level if :on_op == name_t[:kind] and '::' == name_t[:text] then # bug name_t = get_tk container = @top_level given_name << '::' end skip_tkspace_without_nl given_name << name_t[:text] is_self = name_t[:kind] == :on_op && name_t[:text] == '<<' new_modules = [] while !is_self && (tk = peek_tk) and :on_op == tk[:kind] and '::' == tk[:text] do prev_container = container container = container.find_module_named name_t[:text] container ||= if ignore_constants then c = RDoc::NormalModule.new name_t[:text] c.store = @store new_modules << [prev_container, c] c else c = prev_container.add_module RDoc::NormalModule, name_t[:text] c.ignore unless prev_container.document_children @top_level.add_to_classes_or_modules c c end record_location container get_tk skip_tkspace if :on_lparen == peek_tk[:kind] # ProcObjectInConstant::() parse_method_or_yield_parameters break end name_t = get_tk unless :on_const == name_t[:kind] || :on_ident == name_t[:kind] raise RDoc::Error, "Invalid class or module definition: #{given_name}" end if prev_container == container and !ignore_constants given_name = name_t[:text] else given_name << '::' + name_t[:text] end end skip_tkspace_without_nl return [container, name_t, given_name, new_modules] end ## # Skip opening parentheses and yield the block. # Skip closing parentheses too when exists. def skip_parentheses(&block) left_tk = peek_tk if :on_lparen == left_tk[:kind] get_tk ret = skip_parentheses(&block) right_tk = peek_tk if :on_rparen == right_tk[:kind] get_tk end ret else yield end end ## # Return a superclass, which can be either a constant of an expression def get_class_specification tk = peek_tk if tk.nil? return '' elsif :on_kw == tk[:kind] && 'self' == tk[:text] return 'self' elsif :on_gvar == tk[:kind] return '' end res = get_constant skip_tkspace_without_nl get_tkread # empty out read buffer tk = get_tk return res unless tk case tk[:kind] when :on_nl, :on_comment, :on_embdoc, :on_semicolon then unget_tk(tk) return res end res += parse_call_parameters(tk) res end ## # Parse a constant, which might be qualified by one or more class or module # names def get_constant res = "" skip_tkspace_without_nl tk = get_tk while tk && ((:on_op == tk[:kind] && '::' == tk[:text]) || :on_const == tk[:kind]) do res += tk[:text] tk = get_tk end unget_tk(tk) res end ## # Get an included module that may be surrounded by parens def get_included_module_with_optional_parens skip_tkspace_without_nl get_tkread tk = get_tk end_token = get_end_token tk return '' unless end_token nest = 0 continue = false only_constant = true while tk != nil do is_element_of_constant = false case tk[:kind] when :on_semicolon then break if nest == 0 when :on_lbracket then nest += 1 when :on_rbracket then nest -= 1 when :on_lbrace then nest += 1 when :on_rbrace then nest -= 1 if nest <= 0 # we might have a.each { |i| yield i } unget_tk(tk) if nest < 0 break end when :on_lparen then nest += 1 when end_token[:kind] then if end_token[:kind] == :on_rparen nest -= 1 break if nest <= 0 else break if nest <= 0 end when :on_rparen then nest -= 1 when :on_comment, :on_embdoc then @read.pop if :on_nl == end_token[:kind] and "\n" == tk[:text][-1] and (!continue or (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0) then break if !continue and nest <= 0 end when :on_comma then continue = true when :on_ident then continue = false if continue when :on_kw then case tk[:text] when 'def', 'do', 'case', 'for', 'begin', 'class', 'module' nest += 1 when 'if', 'unless', 'while', 'until', 'rescue' # postfix if/unless/while/until/rescue must be EXPR_LABEL nest += 1 unless (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0 when 'end' nest -= 1 break if nest == 0 end when :on_const then is_element_of_constant = true when :on_op then is_element_of_constant = true if '::' == tk[:text] end only_constant = false unless is_element_of_constant tk = get_tk end if only_constant get_tkread_clean(/\s+/, ' ') else '' end end ## # Little hack going on here. In the statement: # # f = 2*(1+yield) # # We see the RPAREN as the next token, so we need to exit early. This still # won't catch all cases (such as "a = yield + 1" def get_end_token tk # :nodoc: case tk[:kind] when :on_lparen token = RDoc::Parser::RipperStateLex::Token.new token[:kind] = :on_rparen token[:text] = ')' token when :on_rparen nil else token = RDoc::Parser::RipperStateLex::Token.new token[:kind] = :on_nl token[:text] = "\n" token end end ## # Retrieves the method container for a singleton method. def get_method_container container, name_t # :nodoc: prev_container = container container = container.find_module_named(name_t[:text]) unless container then constant = prev_container.constants.find do |const| const.name == name_t[:text] end if constant then parse_method_dummy prev_container return end end unless container then # TODO seems broken, should starting at Object in @store obj = name_t[:text].split("::").inject(Object) do |state, item| state.const_get(item) end rescue nil type = obj.class == Class ? RDoc::NormalClass : RDoc::NormalModule unless [Class, Module].include?(obj.class) then warn("Couldn't find #{name_t[:text]}. Assuming it's a module") end if type == RDoc::NormalClass then sclass = obj.superclass ? obj.superclass.name : nil container = prev_container.add_class type, name_t[:text], sclass else container = prev_container.add_module type, name_t[:text] end record_location container end container end ## # Extracts a name or symbol from the token stream. def get_symbol_or_name tk = get_tk case tk[:kind] when :on_symbol then text = tk[:text].sub(/^:/, '') next_tk = peek_tk if next_tk && :on_op == next_tk[:kind] && '=' == next_tk[:text] then get_tk text << '=' end text when :on_ident, :on_const, :on_gvar, :on_cvar, :on_ivar, :on_op, :on_kw then tk[:text] when :on_tstring, :on_dstring then tk[:text][1..-2] else raise RDoc::Error, "Name or symbol expected (got #{tk})" end end ## # Marks containers between +container+ and +ancestor+ as ignored def suppress_parents container, ancestor # :nodoc: while container and container != ancestor do container.suppress unless container.documented? container = container.parent end end ## # Look for directives in a normal comment block: # # # :stopdoc: # # Don't display comment from this point forward # # This routine modifies its +comment+ parameter. def look_for_directives_in container, comment @preprocess.handle comment, container do |directive, param| case directive when 'method', 'singleton-method', 'attr', 'attr_accessor', 'attr_reader', 'attr_writer' then false # handled elsewhere when 'section' then break unless container.kind_of?(RDoc::Context) container.set_current_section param, comment.dup comment.text = '' break end end comment.remove_private end ## # Adds useful info about the parser to +message+ def make_message message prefix = "#{@file_name}:".dup tk = peek_tk prefix << "#{tk[:line_no]}:#{tk[:char_no]}:" if tk "#{prefix} #{message}" end ## # Creates a comment with the correct format def new_comment comment, line_no = nil c = RDoc::Comment.new comment, @top_level, :ruby c.line = line_no c.format = @markup c end ## # Creates an RDoc::Attr for the name following +tk+, setting the comment to # +comment+. def parse_attr(context, single, tk, comment) line_no = tk[:line_no] args = parse_symbol_arg 1 if args.size > 0 then name = args[0] rw = "R" skip_tkspace_without_nl tk = get_tk if :on_comma == tk[:kind] then rw = "RW" if get_bool else unget_tk tk end att = create_attr context, single, name, rw, comment att.line = line_no read_documentation_modifiers att, RDoc::ATTR_MODIFIERS else warn "'attr' ignored - looks like a variable" end end ## # Creates an RDoc::Attr for each attribute listed after +tk+, setting the # comment for each to +comment+. def parse_attr_accessor(context, single, tk, comment) line_no = tk[:line_no] args = parse_symbol_arg rw = "?" tmp = RDoc::CodeObject.new read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS # TODO In most other places we let the context keep track of document_self # and add found items appropriately but here we do not. I'm not sure why. return if @track_visibility and not tmp.document_self case tk[:text] when "attr_reader" then rw = "R" when "attr_writer" then rw = "W" when "attr_accessor" then rw = "RW" else rw = '?' end for name in args att = create_attr context, single, name, rw, comment att.line = line_no end end ## # Parses an +alias+ in +context+ with +comment+ def parse_alias(context, single, tk, comment) line_no = tk[:line_no] skip_tkspace if :on_lparen === peek_tk[:kind] then get_tk skip_tkspace end new_name = get_symbol_or_name skip_tkspace if :on_comma === peek_tk[:kind] then get_tk skip_tkspace end begin old_name = get_symbol_or_name rescue RDoc::Error return end al = RDoc::Alias.new(get_tkread, old_name, new_name, comment, single == SINGLE) record_location al al.line = line_no read_documentation_modifiers al, RDoc::ATTR_MODIFIERS context.add_alias al @stats.add_alias al al end ## # Extracts call parameters from the token stream. def parse_call_parameters(tk) end_token = case tk[:kind] when :on_lparen :on_rparen when :on_rparen return "" else :on_nl end nest = 0 loop do break if tk.nil? case tk[:kind] when :on_semicolon break when :on_lparen nest += 1 when end_token if end_token == :on_rparen nest -= 1 break if RDoc::Parser::RipperStateLex.end?(tk) and nest <= 0 else break if RDoc::Parser::RipperStateLex.end?(tk) end when :on_comment, :on_embdoc unget_tk(tk) break when :on_op if tk[:text] =~ /^(.{1,2})?=$/ unget_tk(tk) break end end tk = get_tk end get_tkread_clean "\n", " " end ## # Parses a class in +context+ with +comment+ def parse_class container, single, tk, comment line_no = tk[:line_no] declaration_context = container container, name_t, given_name, = get_class_or_module container if name_t[:kind] == :on_const cls = parse_class_regular container, declaration_context, single, name_t, given_name, comment elsif name_t[:kind] == :on_op && name_t[:text] == '<<' case name = skip_parentheses { get_class_specification } when 'self', container.name read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS parse_statements container, SINGLE return # don't update line else cls = parse_class_singleton container, name, comment end else warn "Expected class name or '<<'. Got #{name_t[:kind]}: #{name_t[:text].inspect}" return end cls.line = line_no # after end modifiers read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS cls end ## # Parses and creates a regular class def parse_class_regular container, declaration_context, single, # :nodoc: name_t, given_name, comment superclass = '::Object' if given_name =~ /^::/ then declaration_context = @top_level given_name = $' end tk = peek_tk if tk[:kind] == :on_op && tk[:text] == '<' then get_tk skip_tkspace superclass = get_class_specification superclass = '(unknown)' if superclass.empty? end cls_type = single == SINGLE ? RDoc::SingleClass : RDoc::NormalClass cls = declaration_context.add_class cls_type, given_name, superclass cls.ignore unless container.document_children read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS record_location cls cls.add_comment comment, @top_level @top_level.add_to_classes_or_modules cls @stats.add_class cls suppress_parents container, declaration_context unless cls.document_self parse_statements cls cls end ## # Parses a singleton class in +container+ with the given +name+ and # +comment+. def parse_class_singleton container, name, comment # :nodoc: other = @store.find_class_named name unless other then if name =~ /^::/ then name = $' container = @top_level end other = container.add_module RDoc::NormalModule, name record_location other # class << $gvar other.ignore if name.empty? other.add_comment comment, @top_level end # notify :nodoc: all if not a constant-named class/module # (and remove any comment) unless name =~ /\A(::)?[A-Z]/ then other.document_self = nil other.document_children = false other.clear_comment end @top_level.add_to_classes_or_modules other @stats.add_class other read_documentation_modifiers other, RDoc::CLASS_MODIFIERS parse_statements(other, SINGLE) other end ## # Parses a constant in +context+ with +comment+. If +ignore_constants+ is # true, no found constants will be added to RDoc. def parse_constant container, tk, comment, ignore_constants = false line_no = tk[:line_no] name = tk[:text] skip_tkspace_without_nl return unless name =~ /^\w+$/ new_modules = [] if :on_op == peek_tk[:kind] && '::' == peek_tk[:text] then unget_tk tk container, name_t, _, new_modules = get_class_or_module container, true name = name_t[:text] end is_array_or_hash = false if peek_tk && :on_lbracket == peek_tk[:kind] get_tk nest = 1 while bracket_tk = get_tk case bracket_tk[:kind] when :on_lbracket nest += 1 when :on_rbracket nest -= 1 break if nest == 0 end end skip_tkspace_without_nl is_array_or_hash = true end unless peek_tk && :on_op == peek_tk[:kind] && '=' == peek_tk[:text] then return false end get_tk unless ignore_constants new_modules.each do |prev_c, new_module| prev_c.add_module_by_normal_module new_module new_module.ignore unless prev_c.document_children @top_level.add_to_classes_or_modules new_module end end value = '' con = RDoc::Constant.new name, value, comment body = parse_constant_body container, con, is_array_or_hash return unless body con.value = body record_location con con.line = line_no read_documentation_modifiers con, RDoc::CONSTANT_MODIFIERS return if is_array_or_hash @stats.add_constant con container.add_constant con true end def parse_constant_body container, constant, is_array_or_hash # :nodoc: nest = 0 rhs_name = ''.dup get_tkread tk = get_tk body = nil loop do break if tk.nil? if :on_semicolon == tk[:kind] then break if nest <= 0 elsif [:on_tlambeg, :on_lparen, :on_lbrace, :on_lbracket].include?(tk[:kind]) then nest += 1 elsif (:on_kw == tk[:kind] && 'def' == tk[:text]) then nest += 1 elsif (:on_kw == tk[:kind] && %w{do if unless case begin}.include?(tk[:text])) then if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0 nest += 1 end elsif [:on_rparen, :on_rbrace, :on_rbracket].include?(tk[:kind]) || (:on_kw == tk[:kind] && 'end' == tk[:text]) then nest -= 1 elsif (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then unget_tk tk if nest <= 0 and RDoc::Parser::RipperStateLex.end?(tk) then body = get_tkread_clean(/^[ \t]+/, '') read_documentation_modifiers constant, RDoc::CONSTANT_MODIFIERS break else read_documentation_modifiers constant, RDoc::CONSTANT_MODIFIERS end elsif :on_const == tk[:kind] then rhs_name << tk[:text] next_tk = peek_tk if nest <= 0 and (next_tk.nil? || :on_nl == next_tk[:kind]) then create_module_alias container, constant, rhs_name unless is_array_or_hash break end elsif :on_nl == tk[:kind] then if nest <= 0 and RDoc::Parser::RipperStateLex.end?(tk) then unget_tk tk break end elsif :on_op == tk[:kind] && '::' == tk[:text] rhs_name << '::' end tk = get_tk end body ? body : get_tkread_clean(/^[ \t]+/, '') end ## # Generates an RDoc::Method or RDoc::Attr from +comment+ by looking for # :method: or :attr: directives in +comment+. def parse_comment container, tk, comment return parse_comment_tomdoc container, tk, comment if @markup == 'tomdoc' column = tk[:char_no] line_no = comment.line.nil? ? tk[:line_no] : comment.line comment.text = comment.text.sub(/(^# +:?)(singleton-)(method:)/, '\1\3') singleton = !!$~ co = if (comment.text = comment.text.sub(/^# +:?method: *(\S*).*?\n/i, '')) && !!$~ then line_no += $`.count("\n") parse_comment_ghost container, comment.text, $1, column, line_no, comment elsif (comment.text = comment.text.sub(/# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i, '')) && !!$~ then parse_comment_attr container, $1, $3, comment end if co then co.singleton = singleton co.line = line_no end true end ## # Parse a comment that is describing an attribute in +container+ with the # given +name+ and +comment+. def parse_comment_attr container, type, name, comment # :nodoc: return if name.empty? rw = case type when 'attr_reader' then 'R' when 'attr_writer' then 'W' else 'RW' end create_attr container, NORMAL, name, rw, comment end def parse_comment_ghost container, text, name, column, line_no, # :nodoc: comment name = nil if name.empty? meth = RDoc::GhostMethod.new get_tkread, name record_location meth meth.start_collecting_tokens indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column) position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment) position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}" newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n") meth.add_tokens [position_comment, newline, indent] meth.params = if text.sub!(/^#\s+:?args?:\s*(.*?)\s*$/i, '') then $1 else '' end comment.normalize comment.extract_call_seq meth return unless meth.name container.add_method meth meth.comment = comment @stats.add_method meth meth end ## # Creates an RDoc::Method on +container+ from +comment+ if there is a # Signature section in the comment def parse_comment_tomdoc container, tk, comment return unless signature = RDoc::TomDoc.signature(comment) column = tk[:char_no] line_no = tk[:line_no] name, = signature.split %r%[ \(]%, 2 meth = RDoc::GhostMethod.new get_tkread, name record_location meth meth.line = line_no meth.start_collecting_tokens indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column) position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment) position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}" newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n") meth.add_tokens [position_comment, newline, indent] meth.call_seq = signature comment.normalize return unless meth.name container.add_method meth meth.comment = comment @stats.add_method meth end ## # Parses an +include+ or +extend+, indicated by the +klass+ and adds it to # +container+ # with +comment+ def parse_extend_or_include klass, container, comment # :nodoc: loop do skip_tkspace_comment name = get_included_module_with_optional_parens unless name.empty? then obj = container.add klass, name, comment record_location obj end return if peek_tk.nil? || :on_comma != peek_tk[:kind] get_tk end end ## # Parses an +included+ with a block feature of ActiveSupport::Concern. def parse_included_with_activesupport_concern container, comment # :nodoc: skip_tkspace_without_nl tk = get_tk unless tk[:kind] == :on_lbracket || (tk[:kind] == :on_kw && tk[:text] == 'do') unget_tk tk return nil # should be a block end parse_statements container container end ## # Parses identifiers that can create new methods or change visibility. # # Returns true if the comment was not consumed. def parse_identifier container, single, tk, comment # :nodoc: case tk[:text] when 'private', 'protected', 'public', 'private_class_method', 'public_class_method', 'module_function' then parse_visibility container, single, tk return true when 'private_constant', 'public_constant' parse_constant_visibility container, single, tk return true when 'attr' then parse_attr container, single, tk, comment when /^attr_(reader|writer|accessor)$/ then parse_attr_accessor container, single, tk, comment when 'alias_method' then parse_alias container, single, tk, comment when 'require', 'include' then # ignore else if comment.text =~ /\A#\#$/ then case comment.text when /^# +:?attr(_reader|_writer|_accessor)?:/ then parse_meta_attr container, single, tk, comment else method = parse_meta_method container, single, tk, comment method.params = container.params if container.params method.block_params = container.block_params if container.block_params end end end false end ## # Parses a meta-programmed attribute and creates an RDoc::Attr. # # To create foo and bar attributes on class C with comment "My attributes": # # class C # # ## # # :attr: # # # # My attributes # # my_attr :foo, :bar # # end # # To create a foo attribute on class C with comment "My attribute": # # class C # # ## # # :attr: foo # # # # My attribute # # my_attr :foo, :bar # # end def parse_meta_attr(context, single, tk, comment) args = parse_symbol_arg rw = "?" # If nodoc is given, don't document any of them tmp = RDoc::CodeObject.new read_documentation_modifiers tmp, RDoc::ATTR_MODIFIERS regexp = /^# +:?(attr(_reader|_writer|_accessor)?): *(\S*).*?\n/i if regexp =~ comment.text then comment.text = comment.text.sub(regexp, '') rw = case $1 when 'attr_reader' then 'R' when 'attr_writer' then 'W' else 'RW' end name = $3 unless $3.empty? end if name then att = create_attr context, single, name, rw, comment else args.each do |attr_name| att = create_attr context, single, attr_name, rw, comment end end att end ## # Parses a meta-programmed method def parse_meta_method(container, single, tk, comment) column = tk[:char_no] line_no = tk[:line_no] start_collecting_tokens add_token tk add_token_listener self skip_tkspace_without_nl comment.text = comment.text.sub(/(^# +:?)(singleton-)(method:)/, '\1\3') singleton = !!$~ name = parse_meta_method_name comment, tk return unless name meth = RDoc::MetaMethod.new get_tkread, name record_location meth meth.line = line_no meth.singleton = singleton remove_token_listener self meth.start_collecting_tokens indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column) position_comment = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment) position_comment[:text] = "# File #{@top_level.relative_name}, line #{line_no}" newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n") meth.add_tokens [position_comment, newline, indent] meth.add_tokens @token_stream parse_meta_method_params container, single, meth, tk, comment meth.comment = comment @stats.add_method meth meth end ## # Parses the name of a metaprogrammed method. +comment+ is used to # determine the name while +tk+ is used in an error message if the name # cannot be determined. def parse_meta_method_name comment, tk # :nodoc: if comment.text.sub!(/^# +:?method: *(\S*).*?\n/i, '') then return $1 unless $1.empty? end name_t = get_tk if :on_symbol == name_t[:kind] then name_t[:text][1..-1] elsif :on_tstring == name_t[:kind] then name_t[:text][1..-2] elsif :on_op == name_t[:kind] && '=' == name_t[:text] then # ignore remove_token_listener self nil else warn "unknown name token #{name_t.inspect} for meta-method '#{tk[:text]}'" 'unknown' end end ## # Parses the parameters and block for a meta-programmed method. def parse_meta_method_params container, single, meth, tk, comment # :nodoc: token_listener meth do meth.params = '' look_for_directives_in meth, comment comment.normalize comment.extract_call_seq meth container.add_method meth last_tk = tk while tk = get_tk do if :on_semicolon == tk[:kind] then break elsif :on_nl == tk[:kind] then break unless last_tk and :on_comma == last_tk[:kind] elsif :on_sp == tk[:kind] then # expression continues elsif :on_kw == tk[:kind] && 'do' == tk[:text] then parse_statements container, single, meth break else last_tk = tk end end end end ## # Parses a normal method defined by +def+ def parse_method(container, single, tk, comment) singleton = nil added_container = false name = nil column = tk[:char_no] line_no = tk[:line_no] start_collecting_tokens add_token tk token_listener self do prev_container = container name, container, singleton = parse_method_name container added_container = container != prev_container end return unless name meth = RDoc::AnyMethod.new get_tkread, name look_for_directives_in meth, comment meth.singleton = single == SINGLE ? true : singleton record_location meth meth.line = line_no meth.start_collecting_tokens indent = RDoc::Parser::RipperStateLex::Token.new(1, 1, :on_sp, ' ' * column) token = RDoc::Parser::RipperStateLex::Token.new(line_no, 1, :on_comment) token[:text] = "# File #{@top_level.relative_name}, line #{line_no}" newline = RDoc::Parser::RipperStateLex::Token.new(0, 0, :on_nl, "\n") meth.add_tokens [token, newline, indent] meth.add_tokens @token_stream parse_method_params_and_body container, single, meth, added_container comment.normalize comment.extract_call_seq meth meth.comment = comment # after end modifiers read_documentation_modifiers meth, RDoc::METHOD_MODIFIERS @stats.add_method meth end ## # Parses the parameters and body of +meth+ def parse_method_params_and_body container, single, meth, added_container token_listener meth do parse_method_parameters meth if meth.document_self or not @track_visibility then container.add_method meth elsif added_container then container.document_self = false end # Having now read the method parameters and documentation modifiers, we # now know whether we have to rename #initialize to ::new if meth.name == "initialize" && !meth.singleton then if meth.dont_rename_initialize then meth.visibility = :protected else meth.singleton = true meth.name = "new" meth.visibility = :public end end parse_statements container, single, meth end end ## # Parses a method that needs to be ignored. def parse_method_dummy container dummy = RDoc::Context.new dummy.parent = container dummy.store = container.store skip_method dummy end ## # Parses the name of a method in +container+. # # Returns the method name, the container it is in (for def Foo.name) and if # it is a singleton or regular method. def parse_method_name container # :nodoc: skip_tkspace name_t = get_tk back_tk = skip_tkspace_without_nl singleton = false dot = get_tk if dot[:kind] == :on_period || (dot[:kind] == :on_op && dot[:text] == '::') then singleton = true name, container = parse_method_name_singleton container, name_t else unget_tk dot back_tk.reverse_each do |token| unget_tk token end name = parse_method_name_regular container, name_t end return name, container, singleton end ## # For the given +container+ and initial name token +name_t+ the method name # is parsed from the token stream for a regular method. def parse_method_name_regular container, name_t # :nodoc: if :on_op == name_t[:kind] && (%w{* & [] []= <<}.include?(name_t[:text])) then name_t[:text] else unless [:on_kw, :on_const, :on_ident].include?(name_t[:kind]) then warn "expected method name token, . or ::, got #{name_t.inspect}" skip_method container return end name_t[:text] end end ## # For the given +container+ and initial name token +name_t+ the method name # and the new +container+ (if necessary) are parsed from the token stream # for a singleton method. def parse_method_name_singleton container, name_t # :nodoc: skip_tkspace name_t2 = get_tk if (:on_kw == name_t[:kind] && 'self' == name_t[:text]) || (:on_op == name_t[:kind] && '%' == name_t[:text]) then # NOTE: work around '[' being consumed early if :on_lbracket == name_t2[:kind] get_tk name = '[]' else name = name_t2[:text] end elsif :on_const == name_t[:kind] then name = name_t2[:text] container = get_method_container container, name_t return unless container name elsif :on_ident == name_t[:kind] || :on_ivar == name_t[:kind] || :on_gvar == name_t[:kind] then parse_method_dummy container name = nil elsif (:on_kw == name_t[:kind]) && ('true' == name_t[:text] || 'false' == name_t[:text] || 'nil' == name_t[:text]) then klass_name = "#{name_t[:text].capitalize}Class" container = @store.find_class_named klass_name container ||= @top_level.add_class RDoc::NormalClass, klass_name name = name_t2[:text] else warn "unexpected method name token #{name_t.inspect}" # break skip_method container name = nil end return name, container end ## # Extracts +yield+ parameters from +method+ def parse_method_or_yield_parameters(method = nil, modifiers = RDoc::METHOD_MODIFIERS) skip_tkspace_without_nl tk = get_tk end_token = get_end_token tk return '' unless end_token nest = 0 continue = false while tk != nil do case tk[:kind] when :on_semicolon then break if nest == 0 when :on_lbracket then nest += 1 when :on_rbracket then nest -= 1 when :on_lbrace then nest += 1 when :on_rbrace then nest -= 1 if nest <= 0 # we might have a.each { |i| yield i } unget_tk(tk) if nest < 0 break end when :on_lparen then nest += 1 when end_token[:kind] then if end_token[:kind] == :on_rparen nest -= 1 break if nest <= 0 else break end when :on_rparen then nest -= 1 when :on_comment, :on_embdoc then @read.pop if :on_nl == end_token[:kind] and "\n" == tk[:text][-1] and (!continue or (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) != 0) then if method && method.block_params.nil? then unget_tk tk read_documentation_modifiers method, modifiers end break if !continue and nest <= 0 end when :on_comma then continue = true when :on_ident then continue = false if continue end tk = get_tk end get_tkread_clean(/\s+/, ' ') end ## # Capture the method's parameters. Along the way, look for a comment # containing: # # # yields: .... # # and add this as the block_params for the method def parse_method_parameters method res = parse_method_or_yield_parameters method res = "(#{res})" unless res =~ /\A\(/ method.params = res unless method.params return if method.block_params skip_tkspace_without_nl read_documentation_modifiers method, RDoc::METHOD_MODIFIERS end ## # Parses an RDoc::NormalModule in +container+ with +comment+ def parse_module container, single, tk, comment container, name_t, = get_class_or_module container name = name_t[:text] mod = container.add_module RDoc::NormalModule, name mod.ignore unless container.document_children record_location mod read_documentation_modifiers mod, RDoc::CLASS_MODIFIERS mod.add_comment comment, @top_level parse_statements mod # after end modifiers read_documentation_modifiers mod, RDoc::CLASS_MODIFIERS @stats.add_module mod end ## # Parses an RDoc::Require in +context+ containing +comment+ def parse_require(context, comment) skip_tkspace_comment tk = get_tk if :on_lparen == tk[:kind] then skip_tkspace_comment tk = get_tk end name = tk[:text][1..-2] if :on_tstring == tk[:kind] if name then @top_level.add_require RDoc::Require.new(name, comment) else unget_tk tk end end ## # Parses a rescue def parse_rescue skip_tkspace_without_nl while tk = get_tk case tk[:kind] when :on_nl, :on_semicolon, :on_comment then break when :on_comma then skip_tkspace_without_nl get_tk if :on_nl == peek_tk[:kind] end skip_tkspace_without_nl end end ## # Retrieve comment body without =begin/=end def retrieve_comment_body(tk) if :on_embdoc == tk[:kind] tk[:text].gsub(/\A=begin.*\n/, '').gsub(/=end\n?\z/, '') else tk[:text] end end ## # The core of the Ruby parser. def parse_statements(container, single = NORMAL, current_method = nil, comment = new_comment('')) raise 'no' unless RDoc::Comment === comment comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding nest = 1 save_visibility = container.visibility non_comment_seen = true while tk = get_tk do keep_comment = false try_parse_comment = false non_comment_seen = true unless (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) case tk[:kind] when :on_nl, :on_ignored_nl, :on_comment, :on_embdoc then if :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind] skip_tkspace tk = get_tk else past_tokens = @read.size > 1 ? @read[0..-2] : [] nl_position = 0 past_tokens.reverse.each_with_index do |read_tk, i| if read_tk =~ /^\n$/ then nl_position = (past_tokens.size - 1) - i break elsif read_tk =~ /^#.*\n$/ then nl_position = ((past_tokens.size - 1) - i) + 1 break end end comment_only_line = past_tokens[nl_position..-1].all?{ |c| c =~ /^\s+$/ } unless comment_only_line then tk = get_tk end end if tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) then if non_comment_seen then # Look for RDoc in a comment about to be thrown away non_comment_seen = parse_comment container, tk, comment unless comment.empty? comment = '' comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding end line_no = nil while tk and (:on_comment == tk[:kind] or :on_embdoc == tk[:kind]) do comment_body = retrieve_comment_body(tk) line_no = tk[:line_no] if comment.empty? comment += comment_body comment << "\n" unless comment_body =~ /\n\z/ if comment_body.size > 1 && comment_body =~ /\n\z/ then skip_tkspace_without_nl # leading spaces end tk = get_tk end comment = new_comment comment, line_no unless comment.empty? then look_for_directives_in container, comment if container.done_documenting then throw :eof if RDoc::TopLevel === container container.ongoing_visibility = save_visibility end end keep_comment = true else non_comment_seen = true end unget_tk tk keep_comment = true container.current_line_visibility = nil when :on_kw then case tk[:text] when 'class' then parse_class container, single, tk, comment when 'module' then parse_module container, single, tk, comment when 'def' then parse_method container, single, tk, comment when 'alias' then parse_alias container, single, tk, comment unless current_method when 'yield' then if current_method.nil? then warn "Warning: yield outside of method" if container.document_self else parse_yield container, single, tk, current_method end when 'until', 'while' then if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0 nest += 1 skip_optional_do_after_expression end # Until and While can have a 'do', which shouldn't increase the nesting. # We can't solve the general case, but we can handle most occurrences by # ignoring a do at the end of a line. # 'for' is trickier when 'for' then nest += 1 skip_for_variable skip_optional_do_after_expression when 'case', 'do', 'if', 'unless', 'begin' then if (tk[:state] & RDoc::Parser::RipperStateLex::EXPR_LABEL) == 0 nest += 1 end when 'super' then current_method.calls_super = true if current_method when 'rescue' then parse_rescue when 'end' then nest -= 1 if nest == 0 then container.ongoing_visibility = save_visibility parse_comment container, tk, comment unless comment.empty? return end end when :on_const then unless parse_constant container, tk, comment, current_method then try_parse_comment = true end when :on_ident then if nest == 1 and current_method.nil? then keep_comment = parse_identifier container, single, tk, comment end case tk[:text] when "require" then parse_require container, comment when "include" then parse_extend_or_include RDoc::Include, container, comment when "extend" then parse_extend_or_include RDoc::Extend, container, comment when "included" then parse_included_with_activesupport_concern container, comment end else try_parse_comment = nest == 1 end if try_parse_comment then non_comment_seen = parse_comment container, tk, comment unless comment.empty? keep_comment = false end unless keep_comment then comment = new_comment '' comment = RDoc::Encoding.change_encoding comment, @encoding if @encoding container.params = nil container.block_params = nil end consume_trailing_spaces end container.params = nil container.block_params = nil end ## # Parse up to +no+ symbol arguments def parse_symbol_arg(no = nil) skip_tkspace_comment tk = get_tk if tk[:kind] == :on_lparen parse_symbol_arg_paren no else parse_symbol_arg_space no, tk end end ## # Parses up to +no+ symbol arguments surrounded by () and places them in # +args+. def parse_symbol_arg_paren no # :nodoc: args = [] loop do skip_tkspace_comment if tk1 = parse_symbol_in_arg args.push tk1 break if no and args.size >= no end skip_tkspace_comment case (tk2 = get_tk)[:kind] when :on_rparen break when :on_comma else warn("unexpected token: '#{tk2.inspect}'") if $DEBUG_RDOC break end end args end ## # Parses up to +no+ symbol arguments separated by spaces and places them in # +args+. def parse_symbol_arg_space no, tk # :nodoc: args = [] unget_tk tk if tk = parse_symbol_in_arg args.push tk return args if no and args.size >= no end loop do skip_tkspace_without_nl tk1 = get_tk if tk1.nil? || :on_comma != tk1[:kind] then unget_tk tk1 break end skip_tkspace_comment if tk = parse_symbol_in_arg args.push tk break if no and args.size >= no end end args end ## # Returns symbol text from the next token def parse_symbol_in_arg tk = get_tk if :on_symbol == tk[:kind] then tk[:text].sub(/^:/, '') elsif :on_tstring == tk[:kind] then tk[:text][1..-2] elsif :on_dstring == tk[:kind] or :on_ident == tk[:kind] then nil # ignore else warn("Expected symbol or string, got #{tk.inspect}") if $DEBUG_RDOC nil end end ## # Parses statements in the top-level +container+ def parse_top_level_statements container comment = collect_first_comment look_for_directives_in container, comment throw :eof if container.done_documenting @markup = comment.format # HACK move if to RDoc::Context#comment= container.comment = comment if container.document_self unless comment.empty? parse_statements container, NORMAL, nil, comment end ## # Determines the visibility in +container+ from +tk+ def parse_visibility(container, single, tk) vis_type, vis, singleton = get_visibility_information tk, single skip_tkspace_comment false ptk = peek_tk # Ryan Davis suggested the extension to ignore modifiers, because he # often writes # # protected unless $TESTING # if [:on_nl, :on_semicolon].include?(ptk[:kind]) || (:on_kw == ptk[:kind] && (['if', 'unless'].include?(ptk[:text]))) then container.ongoing_visibility = vis elsif :on_kw == ptk[:kind] && 'def' == ptk[:text] container.current_line_visibility = vis else update_visibility container, vis_type, vis, singleton end end ## # Parses a Module#private_constant or Module#public_constant call from +tk+. def parse_constant_visibility(container, single, tk) args = parse_symbol_arg case tk[:text] when 'private_constant' vis = :private when 'public_constant' vis = :public else raise RDoc::Error, 'Unreachable' end container.set_constant_visibility_for args, vis end ## # Determines the block parameter for +context+ def parse_yield(context, single, tk, method) return if method.block_params get_tkread method.block_params = parse_method_or_yield_parameters end ## # Directives are modifier comments that can appear after class, module, or # method names. For example: # # def fred # :yields: a, b # # or: # # class MyClass # :nodoc: # # We return the directive name and any parameters as a two element array if # the name is in +allowed+. A directive can be found anywhere up to the end # of the current line. def read_directive allowed tokens = [] while tk = get_tk do tokens << tk if :on_nl == tk[:kind] or (:on_kw == tk[:kind] && 'def' == tk[:text]) then return elsif :on_comment == tk[:kind] or :on_embdoc == tk[:kind] then return unless tk[:text] =~ /\s*:?([\w-]+):\s*(.*)/ directive = $1.downcase return [directive, $2] if allowed.include? directive return end end ensure unless tokens.length == 1 and (:on_comment == tokens.first[:kind] or :on_embdoc == tokens.first[:kind]) then tokens.reverse_each do |token| unget_tk token end end end ## # Handles directives following the definition for +context+ (any # RDoc::CodeObject) if the directives are +allowed+ at this point. # # See also RDoc::Markup::PreProcess#handle_directive def read_documentation_modifiers context, allowed skip_tkspace_without_nl directive, value = read_directive allowed return unless directive @preprocess.handle_directive '', directive, value, context do |dir, param| if %w[notnew not_new not-new].include? dir then context.dont_rename_initialize = true true end end end ## # Records the location of this +container+ in the file for this parser and # adds it to the list of classes and modules in the file. def record_location container # :nodoc: case container when RDoc::ClassModule then @top_level.add_to_classes_or_modules container end container.record_location @top_level end ## # Scans this Ruby file for Ruby constructs def scan reset catch :eof do begin parse_top_level_statements @top_level rescue StandardError => e if @content.include?('<%') and @content.include?('%>') then # Maybe, this is ERB. $stderr.puts "\033[2KRDoc detects ERB file. Skips it for compatibility:" $stderr.puts @file_name return end if @scanner_point >= @scanner.size now_line_no = @scanner[@scanner.size - 1][:line_no] else now_line_no = peek_tk[:line_no] end first_tk_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no } last_tk_index = @scanner.find_index { |tk| tk[:line_no] == now_line_no + 1 } last_tk_index = last_tk_index ? last_tk_index - 1 : @scanner.size - 1 code = @scanner[first_tk_index..last_tk_index].map{ |t| t[:text] }.join $stderr.puts <<-EOF #{self.class} failure around line #{now_line_no} of #{@file_name} EOF unless code.empty? then $stderr.puts code $stderr.puts end raise e end end @top_level end ## # while, until, and for have an optional do def skip_optional_do_after_expression skip_tkspace_without_nl tk = get_tk b_nest = 0 nest = 0 loop do break unless tk case tk[:kind] when :on_semicolon, :on_nl, :on_ignored_nl then break if b_nest.zero? when :on_lparen then nest += 1 when :on_rparen then nest -= 1 when :on_kw then case tk[:text] when 'begin' b_nest += 1 when 'end' b_nest -= 1 when 'do' break if nest.zero? end when :on_comment, :on_embdoc then if b_nest.zero? and "\n" == tk[:text][-1] then break end end tk = get_tk end skip_tkspace_without_nl get_tk if peek_tk && :on_kw == peek_tk[:kind] && 'do' == peek_tk[:text] end ## # skip the var [in] part of a 'for' statement def skip_for_variable skip_tkspace_without_nl get_tk skip_tkspace_without_nl tk = get_tk unget_tk(tk) unless :on_kw == tk[:kind] and 'in' == tk[:text] end ## # Skips the next method in +container+ def skip_method container meth = RDoc::AnyMethod.new "", "anon" parse_method_parameters meth parse_statements container, false, meth end ## # Skip spaces until a comment is found def skip_tkspace_comment(skip_nl = true) loop do skip_nl ? skip_tkspace : skip_tkspace_without_nl next_tk = peek_tk return if next_tk.nil? || (:on_comment != next_tk[:kind] and :on_embdoc != next_tk[:kind]) get_tk end end ## # Updates visibility in +container+ from +vis_type+ and +vis+. def update_visibility container, vis_type, vis, singleton # :nodoc: new_methods = [] case vis_type when 'module_function' then args = parse_symbol_arg container.set_visibility_for args, :private, false container.methods_matching args do |m| s_m = m.dup record_location s_m s_m.singleton = true new_methods << s_m end when 'public_class_method', 'private_class_method' then args = parse_symbol_arg container.methods_matching args, true do |m| if m.parent != container then m = m.dup record_location m new_methods << m end m.visibility = vis end else args = parse_symbol_arg container.set_visibility_for args, vis, singleton end new_methods.each do |method| case method when RDoc::AnyMethod then container.add_method method when RDoc::Attr then container.add_attribute method end method.visibility = vis end end ## # Prints +message+ to +$stderr+ unless we're being quiet def warn message @options.warn make_message message end end PK!h\;!;!parser/changelog.rbnu[# frozen_string_literal: true ## # A ChangeLog file parser. # # This parser converts a ChangeLog into an RDoc::Markup::Document. When # viewed as HTML a ChangeLog page will have an entry for each day's entries in # the sidebar table of contents. # # This parser is meant to parse the MRI ChangeLog, but can be used to parse any # {GNU style Change # Log}[http://www.gnu.org/prep/standards/html_node/Style-of-Change-Logs.html]. class RDoc::Parser::ChangeLog < RDoc::Parser include RDoc::Parser::Text parse_files_matching(/(\/|\\|\A)ChangeLog[^\/\\]*\z/) ## # Attaches the +continuation+ of the previous line to the +entry_body+. # # Continued function listings are joined together as a single entry. # Continued descriptions are joined to make a single paragraph. def continue_entry_body entry_body, continuation return unless last = entry_body.last if last =~ /\)\s*\z/ and continuation =~ /\A\(/ then last.sub!(/\)\s*\z/, ',') continuation = continuation.sub(/\A\(/, '') end if last =~ /\s\z/ then last << continuation else last << ' ' + continuation end end ## # Creates an RDoc::Markup::Document given the +groups+ of ChangeLog entries. def create_document groups doc = RDoc::Markup::Document.new doc.omit_headings_below = 2 doc.file = @top_level doc << RDoc::Markup::Heading.new(1, File.basename(@file_name)) doc << RDoc::Markup::BlankLine.new groups.sort_by do |day,| day end.reverse_each do |day, entries| doc << RDoc::Markup::Heading.new(2, day.dup) doc << RDoc::Markup::BlankLine.new doc.concat create_entries entries end doc end ## # Returns a list of ChangeLog entries an RDoc::Markup nodes for the given # +entries+. def create_entries entries out = [] entries.each do |entry, items| out << RDoc::Markup::Heading.new(3, entry) out << RDoc::Markup::BlankLine.new out << create_items(items) end out end ## # Returns an RDoc::Markup::List containing the given +items+ in the # ChangeLog def create_items items list = RDoc::Markup::List.new :NOTE items.each do |item| item =~ /\A(.*?(?:\([^)]+\))?):\s*/ title = $1 body = $' paragraph = RDoc::Markup::Paragraph.new body list_item = RDoc::Markup::ListItem.new title, paragraph list << list_item end list end ## # Groups +entries+ by date. def group_entries entries @time_cache ||= {} entries.group_by do |title, _| begin time = @time_cache[title] (time || parse_date(title)).strftime '%Y-%m-%d' rescue NoMethodError, ArgumentError time, = title.split ' ', 2 parse_date(time).strftime '%Y-%m-%d' end end end ## # Parse date in ISO-8601, RFC-2822, or default of Git def parse_date(date) case date when /\A\s*(\d+)-(\d+)-(\d+)(?:[ T](\d+):(\d+):(\d+) *([-+]\d\d):?(\d\d))?\b/ Time.new($1, $2, $3, $4, $5, $6, ("#{$7}:#{$8}" if $7)) when /\A\s*\w{3}, +(\d+) (\w{3}) (\d+) (\d+):(\d+):(\d+) *(?:([-+]\d\d):?(\d\d))\b/ Time.new($3, $2, $1, $4, $5, $6, ("#{$7}:#{$8}" if $7)) when /\A\s*\w{3} (\w{3}) +(\d+) (\d+) (\d+):(\d+):(\d+) *(?:([-+]\d\d):?(\d\d))\b/ Time.new($3, $1, $2, $4, $5, $6, ("#{$7}:#{$8}" if $7)) when /\A\s*\w{3} (\w{3}) +(\d+) (\d+):(\d+):(\d+) (\d+)\b/ Time.new($6, $1, $2, $3, $4, $5) else raise ArgumentError, "bad date: #{date}" end end ## # Parses the entries in the ChangeLog. # # Returns an Array of each ChangeLog entry in order of parsing. # # A ChangeLog entry is an Array containing the ChangeLog title (date and # committer) and an Array of ChangeLog items (file and function changed with # description). # # An example result would be: # # [ 'Tue Dec 4 08:33:46 2012 Eric Hodel ', # [ 'README.EXT: Converted to RDoc format', # 'README.EXT.ja: ditto']] def parse_entries @time_cache ||= {} if /\A((?:.*\n){,3})commit\s/ =~ @content class << self; prepend Git; end parse_info($1) return parse_entries end entries = [] entry_name = nil entry_body = [] @content.each_line do |line| case line when /^\s*$/ then next when /^\w.*/ then entries << [entry_name, entry_body] if entry_name entry_name = $& begin time = parse_date entry_name @time_cache[entry_name] = time rescue ArgumentError entry_name = nil end entry_body = [] when /^(\t| {8})?\*\s*(.*)/ then # "\t* file.c (func): ..." entry_body << $2.dup when /^(\t| {8})?\s*(\(.*)/ then # "\t(func): ..." entry = $2 if entry_body.last =~ /:/ then entry_body << entry.dup else continue_entry_body entry_body, entry end when /^(\t| {8})?\s*(.*)/ then continue_entry_body entry_body, $2 end end entries << [entry_name, entry_body] if entry_name entries.reject! do |(entry,_)| entry == nil end entries end ## # Converts the ChangeLog into an RDoc::Markup::Document def scan @time_cache = {} entries = parse_entries grouped_entries = group_entries entries doc = create_document grouped_entries @top_level.comment = doc @top_level end module Git def parse_info(info) /^\s*base-url\s*=\s*(.*\S)/ =~ info @base_url = $1 end def parse_entries entries = [] @content.scan(/^commit\s+(\h{20})\h*\n((?:.+\n)*)\n((?: {4}.*\n+)*)/) do entry_name, header, entry_body = $1, $2, $3.gsub(/^ {4}/, '') # header = header.scan(/^ *(\S+?): +(.*)/).to_h # date = header["CommitDate"] || header["Date"] date = header[/^ *(?:Author)?Date: +(.*)/, 1] author = header[/^ *Author: +(.*)/, 1] begin time = parse_date(header[/^ *CommitDate: +(.*)/, 1] || date) @time_cache[entry_name] = time author.sub!(/\s*<(.*)>/, '') email = $1 entries << [entry_name, [author, email, date, entry_body]] rescue ArgumentError end end entries end def create_entries entries # git log entries have no strictly itemized style like the old # style, just assume Markdown. entries.map do |commit, entry| LogEntry.new(@base_url, commit, *entry) end end LogEntry = Struct.new(:base, :commit, :author, :email, :date, :contents) do HEADING_LEVEL = 3 def initialize(base, commit, author, email, date, contents) case contents when String contents = RDoc::Markdown.parse(contents).parts.each do |body| case body when RDoc::Markup::Heading body.level += HEADING_LEVEL + 1 end end case first = contents[0] when RDoc::Markup::Paragraph contents[0] = RDoc::Markup::Heading.new(HEADING_LEVEL + 1, first.text) end end super end def level HEADING_LEVEL end def aref "label-#{commit}" end def label context = nil aref end def text case base when nil "#{date}" when /%s/ "{#{date}}[#{base % commit}]" else "{#{date}}[#{base}#{commit}]" end + " {#{author}}[mailto:#{email}]" end def accept visitor visitor.accept_heading self begin if visitor.respond_to?(:code_object=) code_object = visitor.code_object visitor.code_object = self end contents.each do |body| body.accept visitor end ensure if visitor.respond_to?(:code_object) visitor.code_object = code_object end end end def pretty_print q # :nodoc: q.group(2, '[log_entry: ', ']') do q.text commit q.text ',' q.breakable q.group(2, '[date: ', ']') { q.text date } q.text ',' q.breakable q.group(2, '[author: ', ']') { q.text author } q.text ',' q.breakable q.group(2, '[email: ', ']') { q.text email } q.text ',' q.breakable q.pp contents end end end end end PK!5s00 servlet.rbnu[# frozen_string_literal: true require_relative '../rdoc' require 'erb' require 'time' require 'json' begin require 'webrick' rescue LoadError abort "webrick is not found. You may need to `gem install webrick` to install webrick." end ## # This is a WEBrick servlet that allows you to browse ri documentation. # # You can show documentation through either `ri --server` or, with RubyGems # 2.0 or newer, `gem server`. For ri, the server runs on port 8214 by # default. For RubyGems the server runs on port 8808 by default. # # You can use this servlet in your own project by mounting it on a WEBrick # server: # # require 'webrick' # # server = WEBrick::HTTPServer.new Port: 8000 # # server.mount '/', RDoc::Servlet # # If you want to mount the servlet some other place than the root, provide the # base path when mounting: # # server.mount '/rdoc', RDoc::Servlet, '/rdoc' class RDoc::Servlet < WEBrick::HTTPServlet::AbstractServlet @server_stores = Hash.new { |hash, server| hash[server] = {} } @cache = Hash.new { |hash, store| hash[store] = {} } ## # Maps an asset type to its path on the filesystem attr_reader :asset_dirs ## # An RDoc::Options instance used for rendering options attr_reader :options ## # Creates an instance of this servlet that shares cached data between # requests. def self.get_instance server, *options # :nodoc: stores = @server_stores[server] new server, stores, @cache, *options end ## # Creates a new WEBrick servlet. # # Use +mount_path+ when mounting the servlet somewhere other than /. # # Use +extra_doc_dirs+ for additional documentation directories. # # +server+ is provided automatically by WEBrick when mounting. +stores+ and # +cache+ are provided automatically by the servlet. def initialize server, stores, cache, mount_path = nil, extra_doc_dirs = [] super server @cache = cache @mount_path = mount_path @extra_doc_dirs = extra_doc_dirs @stores = stores @options = RDoc::Options.new @options.op_dir = '.' darkfish_dir = nil # HACK dup $LOAD_PATH.each do |path| darkfish_dir = File.join path, 'rdoc/generator/template/darkfish/' next unless File.directory? darkfish_dir @options.template_dir = darkfish_dir break end @asset_dirs = { :darkfish => darkfish_dir, :json_index => File.expand_path('../generator/template/json_index/', __FILE__), } end ## # Serves the asset at the path in +req+ for +generator_name+ via +res+. def asset generator_name, req, res asset_dir = @asset_dirs[generator_name] asset_path = File.join asset_dir, req.path if_modified_since req, res, asset_path res.body = File.read asset_path res.content_type = case req.path when /\.css\z/ then 'text/css' when /\.js\z/ then 'application/javascript' else 'application/octet-stream' end end ## # GET request entry point. Fills in +res+ for the path, etc. in +req+. def do_GET req, res req.path.sub!(/\A#{Regexp.escape @mount_path}/, '') if @mount_path case req.path when '/' then root req, res when '/js/darkfish.js', '/js/jquery.js', '/js/search.js', %r%^/css/%, %r%^/images/%, %r%^/fonts/% then asset :darkfish, req, res when '/js/navigation.js', '/js/searcher.js' then asset :json_index, req, res when '/js/search_index.js' then root_search req, res else show_documentation req, res end rescue WEBrick::HTTPStatus::NotFound => e generator = generator_for RDoc::Store.new not_found generator, req, res, e.message rescue WEBrick::HTTPStatus::Status raise rescue => e error e, req, res end ## # Fills in +res+ with the class, module or page for +req+ from +store+. # # +path+ is relative to the mount_path and is used to determine the class, # module or page name (/RDoc/Servlet.html becomes RDoc::Servlet). # +generator+ is used to create the page. def documentation_page store, generator, path, req, res text_name = path.chomp '.html' name = text_name.gsub '/', '::' if klass = store.find_class_or_module(name) then res.body = generator.generate_class klass elsif page = store.find_text_page(name.sub(/_([^_]*)\z/, '.\1')) then res.body = generator.generate_page page elsif page = store.find_text_page(text_name.sub(/_([^_]*)\z/, '.\1')) then res.body = generator.generate_page page else not_found generator, req, res end end ## # Creates the JSON search index on +res+ for the given +store+. +generator+ # must respond to \#json_index to build. +req+ is ignored. def documentation_search store, generator, req, res json_index = @cache[store].fetch :json_index do @cache[store][:json_index] = JSON.dump generator.json_index.build_index end res.content_type = 'application/javascript' res.body = "var search_data = #{json_index}" end ## # Returns the RDoc::Store and path relative to +mount_path+ for # documentation at +path+. def documentation_source path _, source_name, path = path.split '/', 3 store = @stores[source_name] return store, path if store store = store_for source_name store.load_all @stores[source_name] = store return store, path end ## # Generates an error page for the +exception+ while handling +req+ on +res+. def error exception, req, res backtrace = exception.backtrace.join "\n" res.content_type = 'text/html' res.status = 500 res.body = <<-BODY Error - #{ERB::Util.html_escape exception.class}

    Error

    While processing #{ERB::Util.html_escape req.request_uri} the RDoc (#{ERB::Util.html_escape RDoc::VERSION}) server has encountered a #{ERB::Util.html_escape exception.class} exception:

    #{ERB::Util.html_escape exception.message}

    Please report this to the RDoc issues tracker. Please include the RDoc version, the URI above and exception class, message and backtrace. If you're viewing a gem's documentation, include the gem name and version. If you're viewing Ruby's documentation, include the version of ruby.

    Backtrace:

    #{ERB::Util.html_escape backtrace}
    BODY end ## # Instantiates a Darkfish generator for +store+ def generator_for store generator = RDoc::Generator::Darkfish.new store, @options generator.file_output = false generator.asset_rel_path = '..' rdoc = RDoc::RDoc.new rdoc.store = store rdoc.generator = generator rdoc.options = @options @options.main_page = store.main @options.title = store.title generator end ## # Handles the If-Modified-Since HTTP header on +req+ for +path+. If the # file has not been modified a Not Modified response is returned. If the # file has been modified a Last-Modified header is added to +res+. def if_modified_since req, res, path = nil last_modified = File.stat(path).mtime if path res['last-modified'] = last_modified.httpdate return unless ims = req['if-modified-since'] ims = Time.parse ims unless ims < last_modified then res.body = '' raise WEBrick::HTTPStatus::NotModified end end ## # Returns an Array of installed documentation. # # Each entry contains the documentation name (gem name, 'Ruby # Documentation', etc.), the path relative to the mount point, whether the # documentation exists, the type of documentation (See RDoc::RI::Paths#each) # and the filesystem to the RDoc::Store for the documentation. def installed_docs extra_counter = 0 ri_paths.map do |path, type| store = RDoc::Store.new path, type exists = File.exist? store.cache_path case type when :gem then gem_path = path[%r%/([^/]*)/ri$%, 1] [gem_path, "#{gem_path}/", exists, type, path] when :system then ['Ruby Documentation', 'ruby/', exists, type, path] when :site then ['Site Documentation', 'site/', exists, type, path] when :home then ['Home Documentation', 'home/', exists, type, path] when :extra then extra_counter += 1 store.load_cache if exists title = store.title || "Extra Documentation" [title, "extra-#{extra_counter}/", exists, type, path] end end end ## # Returns a 404 page built by +generator+ for +req+ on +res+. def not_found generator, req, res, message = nil message ||= "The page #{ERB::Util.h req.path} was not found" res.body = generator.generate_servlet_not_found message res.status = 404 end ## # Enumerates the ri paths. See RDoc::RI::Paths#each def ri_paths &block RDoc::RI::Paths.each true, true, true, :all, *@extra_doc_dirs, &block #TODO: pass extra_dirs end ## # Generates the root page on +res+. +req+ is ignored. def root req, res generator = RDoc::Generator::Darkfish.new nil, @options res.body = generator.generate_servlet_root installed_docs res.content_type = 'text/html' end ## # Generates a search index for the root page on +res+. +req+ is ignored. def root_search req, res search_index = [] info = [] installed_docs.map do |name, href, exists, type, path| next unless exists search_index << name case type when :gem gemspec = path.gsub(%r%/doc/([^/]*?)/ri$%, '/specifications/\1.gemspec') spec = Gem::Specification.load gemspec path = spec.full_name comment = spec.summary when :system then path = 'ruby' comment = 'Documentation for the Ruby standard library' when :site then path = 'site' comment = 'Documentation for non-gem libraries' when :home then path = 'home' comment = 'Documentation from your home directory' when :extra comment = name end info << [name, '', path, '', comment] end index = { :index => { :searchIndex => search_index, :longSearchIndex => search_index, :info => info, } } res.body = "var search_data = #{JSON.dump index};" res.content_type = 'application/javascript' end ## # Displays documentation for +req+ on +res+, whether that be HTML or some # asset. def show_documentation req, res store, path = documentation_source req.path if_modified_since req, res, store.cache_path generator = generator_for store case path when nil, '', 'index.html' then res.body = generator.generate_index when 'table_of_contents.html' then res.body = generator.generate_table_of_contents when 'js/search_index.js' then documentation_search store, generator, req, res else documentation_page store, generator, path, req, res end ensure res.content_type ||= 'text/html' end ## # Returns an RDoc::Store for the given +source_name+ ('ruby' or a gem name). def store_for source_name case source_name when 'home' then RDoc::Store.new RDoc::RI::Paths.home_dir, :home when 'ruby' then RDoc::Store.new RDoc::RI::Paths.system_dir, :system when 'site' then RDoc::Store.new RDoc::RI::Paths.site_dir, :site when /\Aextra-(\d+)\z/ then index = $1.to_i - 1 ri_dir = installed_docs[index][4] RDoc::Store.new ri_dir, :extra else ri_dir, type = ri_paths.find do |dir, dir_type| next unless dir_type == :gem source_name == dir[%r%/([^/]*)/ri$%, 1] end raise WEBrick::HTTPStatus::NotFound, "Could not find gem \"#{ERB::Util.html_escape(source_name)}\". Are you sure you installed it?" unless ri_dir store = RDoc::Store.new ri_dir, type return store if File.exist? store.cache_path raise WEBrick::HTTPStatus::NotFound, "Could not find documentation for \"#{ERB::Util.html_escape(source_name)}\". Please run `gem rdoc --ri gem_name`" end end end PK!'vvri.rbnu[# frozen_string_literal: true require_relative '../rdoc' ## # Namespace for the ri command line tool's implementation. # # See ri --help for details. module RDoc::RI ## # Base RI error class class Error < RDoc::Error; end autoload :Driver, "#{__dir__}/ri/driver" autoload :Paths, "#{__dir__}/ri/paths" autoload :Store, "#{__dir__}/ri/store" end PK!}}rd/inline_parser.rbnu[# frozen_string_literal: true # # DO NOT MODIFY!!!! # This file is automatically generated by Racc 1.6.0 # from Racc grammar file "". # require 'racc/parser.rb' require 'strscan' class RDoc::RD ## # RD format parser for inline markup such as emphasis, links, footnotes, etc. class InlineParser < Racc::Parser # :stopdoc: EM_OPEN = '((*' EM_OPEN_RE = /\A#{Regexp.quote(EM_OPEN)}/ EM_CLOSE = '*))' EM_CLOSE_RE = /\A#{Regexp.quote(EM_CLOSE)}/ CODE_OPEN = '(({' CODE_OPEN_RE = /\A#{Regexp.quote(CODE_OPEN)}/ CODE_CLOSE = '}))' CODE_CLOSE_RE = /\A#{Regexp.quote(CODE_CLOSE)}/ VAR_OPEN = '((|' VAR_OPEN_RE = /\A#{Regexp.quote(VAR_OPEN)}/ VAR_CLOSE = '|))' VAR_CLOSE_RE = /\A#{Regexp.quote(VAR_CLOSE)}/ KBD_OPEN = '((%' KBD_OPEN_RE = /\A#{Regexp.quote(KBD_OPEN)}/ KBD_CLOSE = '%))' KBD_CLOSE_RE = /\A#{Regexp.quote(KBD_CLOSE)}/ INDEX_OPEN = '((:' INDEX_OPEN_RE = /\A#{Regexp.quote(INDEX_OPEN)}/ INDEX_CLOSE = ':))' INDEX_CLOSE_RE = /\A#{Regexp.quote(INDEX_CLOSE)}/ REF_OPEN = '((<' REF_OPEN_RE = /\A#{Regexp.quote(REF_OPEN)}/ REF_CLOSE = '>))' REF_CLOSE_RE = /\A#{Regexp.quote(REF_CLOSE)}/ FOOTNOTE_OPEN = '((-' FOOTNOTE_OPEN_RE = /\A#{Regexp.quote(FOOTNOTE_OPEN)}/ FOOTNOTE_CLOSE = '-))' FOOTNOTE_CLOSE_RE = /\A#{Regexp.quote(FOOTNOTE_CLOSE)}/ VERB_OPEN = "(('" VERB_OPEN_RE = /\A#{Regexp.quote(VERB_OPEN)}/ VERB_CLOSE = "'))" VERB_CLOSE_RE = /\A#{Regexp.quote(VERB_CLOSE)}/ BAR = "|" BAR_RE = /\A#{Regexp.quote(BAR)}/ QUOTE = '"' QUOTE_RE = /\A#{Regexp.quote(QUOTE)}/ SLASH = "/" SLASH_RE = /\A#{Regexp.quote(SLASH)}/ BACK_SLASH = "\\" BACK_SLASH_RE = /\A#{Regexp.quote(BACK_SLASH)}/ URL = "URL:" URL_RE = /\A#{Regexp.quote(URL)}/ other_re_mode = Regexp::EXTENDED other_re_mode |= Regexp::MULTILINE OTHER_RE = Regexp.new( "\\A.+?(?=#{Regexp.quote(EM_OPEN)}|#{Regexp.quote(EM_CLOSE)}| #{Regexp.quote(CODE_OPEN)}|#{Regexp.quote(CODE_CLOSE)}| #{Regexp.quote(VAR_OPEN)}|#{Regexp.quote(VAR_CLOSE)}| #{Regexp.quote(KBD_OPEN)}|#{Regexp.quote(KBD_CLOSE)}| #{Regexp.quote(INDEX_OPEN)}|#{Regexp.quote(INDEX_CLOSE)}| #{Regexp.quote(REF_OPEN)}|#{Regexp.quote(REF_CLOSE)}| #{Regexp.quote(FOOTNOTE_OPEN)}|#{Regexp.quote(FOOTNOTE_CLOSE)}| #{Regexp.quote(VERB_OPEN)}|#{Regexp.quote(VERB_CLOSE)}| #{Regexp.quote(BAR)}| #{Regexp.quote(QUOTE)}| #{Regexp.quote(SLASH)}| #{Regexp.quote(BACK_SLASH)}| #{Regexp.quote(URL)})", other_re_mode) # :startdoc: ## # Creates a new parser for inline markup in the rd format. The +block_parser+ # is used to for footnotes and labels in the inline text. def initialize block_parser @block_parser = block_parser end ## # Parses the +inline+ text from RD format into RDoc format. def parse inline @inline = inline @src = StringScanner.new inline @pre = "".dup @yydebug = true do_parse.to_s end ## # Returns the next token from the inline text def next_token return [false, false] if @src.eos? # p @src.rest if @yydebug if ret = @src.scan(EM_OPEN_RE) @pre << ret [:EM_OPEN, ret] elsif ret = @src.scan(EM_CLOSE_RE) @pre << ret [:EM_CLOSE, ret] elsif ret = @src.scan(CODE_OPEN_RE) @pre << ret [:CODE_OPEN, ret] elsif ret = @src.scan(CODE_CLOSE_RE) @pre << ret [:CODE_CLOSE, ret] elsif ret = @src.scan(VAR_OPEN_RE) @pre << ret [:VAR_OPEN, ret] elsif ret = @src.scan(VAR_CLOSE_RE) @pre << ret [:VAR_CLOSE, ret] elsif ret = @src.scan(KBD_OPEN_RE) @pre << ret [:KBD_OPEN, ret] elsif ret = @src.scan(KBD_CLOSE_RE) @pre << ret [:KBD_CLOSE, ret] elsif ret = @src.scan(INDEX_OPEN_RE) @pre << ret [:INDEX_OPEN, ret] elsif ret = @src.scan(INDEX_CLOSE_RE) @pre << ret [:INDEX_CLOSE, ret] elsif ret = @src.scan(REF_OPEN_RE) @pre << ret [:REF_OPEN, ret] elsif ret = @src.scan(REF_CLOSE_RE) @pre << ret [:REF_CLOSE, ret] elsif ret = @src.scan(FOOTNOTE_OPEN_RE) @pre << ret [:FOOTNOTE_OPEN, ret] elsif ret = @src.scan(FOOTNOTE_CLOSE_RE) @pre << ret [:FOOTNOTE_CLOSE, ret] elsif ret = @src.scan(VERB_OPEN_RE) @pre << ret [:VERB_OPEN, ret] elsif ret = @src.scan(VERB_CLOSE_RE) @pre << ret [:VERB_CLOSE, ret] elsif ret = @src.scan(BAR_RE) @pre << ret [:BAR, ret] elsif ret = @src.scan(QUOTE_RE) @pre << ret [:QUOTE, ret] elsif ret = @src.scan(SLASH_RE) @pre << ret [:SLASH, ret] elsif ret = @src.scan(BACK_SLASH_RE) @pre << ret [:BACK_SLASH, ret] elsif ret = @src.scan(URL_RE) @pre << ret [:URL, ret] elsif ret = @src.scan(OTHER_RE) @pre << ret [:OTHER, ret] else ret = @src.rest @pre << ret @src.terminate [:OTHER, ret] end end ## # Raises a ParseError when invalid formatting is found def on_error(et, ev, values) lines_of_rest = @src.rest.lines.to_a.length prev_words = prev_words_on_error(ev) at = 4 + prev_words.length message = <<-MSG RD syntax error: line #{@block_parser.line_index - lines_of_rest}: ...#{prev_words} #{(ev||'')} #{next_words_on_error()} ... MSG message << " " * at + "^" * (ev ? ev.length : 0) + "\n" raise ParseError, message end ## # Returns words before the error def prev_words_on_error(ev) pre = @pre if ev and /#{Regexp.quote(ev)}$/ =~ pre pre = $` end last_line(pre) end ## # Returns the last line of +src+ def last_line(src) if n = src.rindex("\n") src[(n+1) .. -1] else src end end private :last_line ## # Returns words following an error def next_words_on_error if n = @src.rest.index("\n") @src.rest[0 .. (n-1)] else @src.rest end end ## # Creates a new RDoc::RD::Inline for the +rdoc+ markup and the raw +reference+ def inline rdoc, reference = rdoc RDoc::RD::Inline.new rdoc, reference end # :stopdoc: ##### State transition tables begin ### racc_action_table = [ 104, 103, 102, 100, 101, 99, 115, 116, 117, 29, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 84, 118, 119, 63, 64, 65, 61, 81, 62, 76, 78, 79, 85, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 80, 149, 63, 64, 65, 153, 81, 62, 76, 78, 79, 86, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 80, 152, 104, 103, 102, 100, 101, 99, 115, 116, 117, 87, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 88, 118, 119, 104, 103, 102, 100, 101, 99, 115, 116, 117, 89, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 96, 118, 119, 104, 103, 102, 100, 101, 99, 115, 116, 117, 124, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 137, 118, 119, 22, 23, 24, 25, 26, 21, 18, 19, 176, 177, 13, 148, 14, 154, 15, 137, 16, 161, 17, 164, 173, 20, 22, 23, 24, 25, 26, 21, 18, 19, 175, 177, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 22, 23, 24, 25, 26, 21, 18, 19, nil, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 22, 23, 24, 25, 26, 21, 18, 19, nil, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 22, 23, 24, 25, 26, 21, 18, 19, nil, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 22, 23, 24, 25, 26, 21, 18, 19, nil, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 22, 23, 24, 25, 26, 21, 18, 19, nil, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, 42, nil, 20, 54, 38, 53, 55, 56, 57, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 22, 23, 24, 25, 26, 21, 18, 19, nil, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 63, 64, 65, 61, 81, 62, 76, 78, 79, nil, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 80, 122, nil, nil, 54, nil, 53, 55, 56, 57, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, 145, nil, 20, 54, 133, 53, 55, 56, 57, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, 145, nil, 20, 54, 133, 53, 55, 56, 57, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, 145, nil, 20, 54, 133, 53, 55, 56, 57, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, 145, nil, 20, 54, 133, 53, 55, 56, 57, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 135, 136, 54, 133, 53, 55, 56, 57, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 135, 136, 54, 133, 53, 55, 56, 57, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, nil, nil, 20, 135, 136, 54, 133, 53, 55, 56, 57, nil, 13, nil, 14, nil, 15, nil, 16, nil, 17, 95, nil, 20, 54, 91, 53, 55, 56, 57, 145, nil, nil, 54, 133, 53, 55, 56, 57, 158, nil, nil, 54, nil, 53, 55, 56, 57, 165, 135, 136, 54, 133, 53, 55, 56, 57, 145, nil, nil, 54, 133, 53, 55, 56, 57, 172, 135, 136, 54, 133, 53, 55, 56, 57, 174, 135, 136, 54, 133, 53, 55, 56, 57, 178, 135, 136, 54, 133, 53, 55, 56, 57, 135, 136, 54, 133, 53, 55, 56, 57, 135, 136, 54, 133, 53, 55, 56, 57, 135, 136, 54, 133, 53, 55, 56, 57, 22, 23, 24, 25, 26, 21 ] racc_action_check = [ 38, 38, 38, 38, 38, 38, 38, 38, 38, 1, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 29, 38, 38, 59, 59, 59, 59, 59, 59, 59, 59, 59, 31, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, 61, 61, 61, 61, 61, 61, 61, 61, 32, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 91, 91, 91, 91, 91, 91, 91, 91, 91, 33, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 34, 91, 91, 97, 97, 97, 97, 97, 97, 97, 97, 97, 35, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 37, 97, 97, 155, 155, 155, 155, 155, 155, 155, 155, 155, 41, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 43, 155, 155, 0, 0, 0, 0, 0, 0, 0, 0, 165, 165, 0, 58, 0, 90, 0, 94, 0, 100, 0, 125, 162, 0, 2, 2, 2, 2, 2, 2, 2, 2, 164, 172, 2, nil, 2, nil, 2, nil, 2, nil, 2, nil, nil, 2, 13, 13, 13, 13, 13, 13, 13, 13, nil, nil, 13, nil, 13, nil, 13, nil, 13, nil, 13, nil, nil, 13, 14, 14, 14, 14, 14, 14, 14, 14, nil, nil, 14, nil, 14, nil, 14, nil, 14, nil, 14, nil, nil, 14, 15, 15, 15, 15, 15, 15, 15, 15, nil, nil, 15, nil, 15, nil, 15, nil, 15, nil, 15, nil, nil, 15, 16, 16, 16, 16, 16, 16, 16, 16, nil, nil, 16, nil, 16, nil, 16, nil, 16, nil, 16, nil, nil, 16, 17, 17, 17, 17, 17, 17, 17, 17, nil, nil, 17, nil, 17, nil, 17, nil, 17, nil, 17, 18, nil, 17, 18, 18, 18, 18, 18, 18, nil, 18, nil, 18, nil, 18, nil, 18, nil, 18, nil, nil, 18, 19, 19, 19, 19, 19, 19, 19, 19, nil, nil, 19, nil, 19, nil, 19, nil, 19, nil, 19, nil, nil, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, nil, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 39, nil, nil, 39, nil, 39, 39, 39, 39, nil, 39, nil, 39, nil, 39, nil, 39, nil, 39, 44, nil, 39, 44, 44, 44, 44, 44, 44, nil, 44, nil, 44, nil, 44, nil, 44, nil, 44, 45, nil, 44, 45, 45, 45, 45, 45, 45, nil, 45, nil, 45, nil, 45, nil, 45, nil, 45, 138, nil, 45, 138, 138, 138, 138, 138, 138, nil, 138, nil, 138, nil, 138, nil, 138, nil, 138, 146, nil, 138, 146, 146, 146, 146, 146, 146, nil, 146, nil, 146, nil, 146, nil, 146, nil, 146, nil, nil, 146, 42, 42, 42, 42, 42, 42, 42, 42, nil, 42, nil, 42, nil, 42, nil, 42, nil, 42, nil, nil, 42, 122, 122, 122, 122, 122, 122, 122, 122, nil, 122, nil, 122, nil, 122, nil, 122, nil, 122, nil, nil, 122, 127, 127, 127, 127, 127, 127, 127, 127, nil, 127, nil, 127, nil, 127, nil, 127, nil, 127, 36, nil, 127, 36, 36, 36, 36, 36, 36, 52, nil, nil, 52, 52, 52, 52, 52, 52, 92, nil, nil, 92, nil, 92, 92, 92, 92, 126, 126, 126, 126, 126, 126, 126, 126, 126, 142, nil, nil, 142, 142, 142, 142, 142, 142, 159, 159, 159, 159, 159, 159, 159, 159, 159, 163, 163, 163, 163, 163, 163, 163, 163, 163, 171, 171, 171, 171, 171, 171, 171, 171, 171, 95, 95, 95, 95, 95, 95, 95, 95, 158, 158, 158, 158, 158, 158, 158, 158, 168, 168, 168, 168, 168, 168, 168, 168, 27, 27, 27, 27, 27, 27 ] racc_action_pointer = [ 135, 9, 157, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 179, 201, 223, 245, 267, 286, 308, 330, nil, nil, nil, nil, nil, nil, 606, nil, 20, nil, 18, 39, 60, 69, 79, 510, 89, -3, 352, nil, 120, 449, 130, 371, 390, nil, nil, nil, nil, nil, nil, 519, nil, nil, nil, nil, nil, 138, 20, 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, 128, 66, 528, nil, 148, 581, nil, 89, nil, nil, 149, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 470, nil, nil, 154, 537, 491, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 409, nil, nil, nil, 546, nil, nil, nil, 428, nil, nil, nil, nil, nil, nil, nil, nil, 112, nil, nil, 589, 555, nil, nil, 155, 564, 164, 142, nil, nil, 597, nil, nil, 573, 164, nil, nil, nil, nil, nil, nil ] racc_action_default = [ -138, -138, -1, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -138, -138, -138, -138, -138, -138, -138, -138, -103, -104, -105, -106, -107, -108, -111, -110, -138, -2, -138, -138, -138, -138, -138, -138, -138, -138, -27, -26, -35, -138, -58, -41, -40, -47, -48, -49, -50, -51, -52, -63, -66, -67, -68, -69, -70, -138, -138, -112, -138, -116, -117, -118, -119, -120, -121, -122, -123, -124, -125, -126, -127, -128, -129, -130, -131, -132, -133, -134, -135, -137, -109, 179, -13, -14, -15, -16, -17, -138, -138, -23, -22, -33, -138, -19, -24, -79, -80, -138, -82, -83, -84, -85, -86, -87, -88, -89, -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, -100, -25, -35, -138, -58, -28, -138, -59, -42, -46, -55, -56, -65, -71, -72, -75, -76, -77, -31, -38, -44, -53, -54, -57, -61, -73, -74, -39, -62, -101, -102, -136, -113, -114, -115, -18, -20, -21, -33, -138, -138, -78, -81, -138, -59, -36, -37, -64, -45, -59, -43, -60, -138, -34, -36, -37, -29, -30, -32, -34 ] racc_goto_table = [ 126, 44, 125, 43, 144, 144, 160, 93, 97, 52, 166, 82, 144, 40, 41, 39, 138, 146, 169, 30, 36, 94, 44, 1, 123, 129, 169, 52, 90, 37, 52, 167, 147, 92, 120, 121, 31, 32, 33, 34, 35, 170, 58, 166, 59, 83, 170, 166, 151, nil, 150, nil, 166, 159, 4, 166, 4, nil, nil, nil, nil, 155, nil, 156, 160, nil, nil, 4, 4, 4, 4, 4, nil, 4, 5, nil, 5, 157, nil, nil, 163, nil, 162, 52, nil, 168, nil, 5, 5, 5, 5, 5, nil, 5, nil, nil, nil, nil, 144, nil, nil, nil, 144, nil, nil, 129, 144, 144, nil, 6, 129, 6, nil, nil, nil, nil, 171, 7, nil, 7, nil, nil, 6, 6, 6, 6, 6, 8, 6, 8, 7, 7, 7, 7, 7, 11, 7, 11, nil, nil, 8, 8, 8, 8, 8, nil, 8, nil, 11, 11, 11, 11, 11, nil, 11 ] racc_goto_check = [ 22, 24, 21, 23, 36, 36, 37, 18, 16, 34, 35, 41, 36, 19, 20, 17, 25, 25, 28, 3, 13, 23, 24, 1, 23, 24, 28, 34, 14, 15, 34, 29, 32, 17, 19, 20, 1, 1, 1, 1, 1, 33, 1, 35, 38, 39, 33, 35, 42, nil, 41, nil, 35, 22, 4, 35, 4, nil, nil, nil, nil, 16, nil, 18, 37, nil, nil, 4, 4, 4, 4, 4, nil, 4, 5, nil, 5, 23, nil, nil, 22, nil, 21, 34, nil, 22, nil, 5, 5, 5, 5, 5, nil, 5, nil, nil, nil, nil, 36, nil, nil, nil, 36, nil, nil, 24, 36, 36, nil, 6, 24, 6, nil, nil, nil, nil, 22, 7, nil, 7, nil, nil, 6, 6, 6, 6, 6, 8, 6, 8, 7, 7, 7, 7, 7, 11, 7, 11, nil, nil, 8, 8, 8, 8, 8, nil, 8, nil, 11, 11, 11, 11, 11, nil, 11 ] racc_goto_pointer = [ nil, 23, nil, 17, 54, 74, 109, 117, 127, nil, nil, 135, nil, 2, -8, 11, -30, -3, -29, -5, -4, -40, -42, -15, -17, -28, nil, nil, -120, -96, nil, nil, -20, -101, -9, -116, -40, -91, 24, 18, nil, -9, -13 ] racc_goto_default = [ nil, nil, 2, 3, 46, 47, 48, 49, 50, 9, 10, 51, 12, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 140, nil, 45, 127, 139, 128, 141, 130, 142, 143, 132, 131, 134, 98, nil, 28, 27, nil, 60 ] racc_reduce_table = [ 0, 0, :racc_error, 1, 27, :_reduce_none, 2, 28, :_reduce_2, 1, 28, :_reduce_3, 1, 29, :_reduce_none, 1, 29, :_reduce_none, 1, 29, :_reduce_none, 1, 29, :_reduce_none, 1, 29, :_reduce_none, 1, 29, :_reduce_none, 1, 29, :_reduce_none, 1, 29, :_reduce_none, 1, 29, :_reduce_none, 3, 30, :_reduce_13, 3, 31, :_reduce_14, 3, 32, :_reduce_15, 3, 33, :_reduce_16, 3, 34, :_reduce_17, 4, 35, :_reduce_18, 3, 35, :_reduce_19, 2, 40, :_reduce_20, 2, 40, :_reduce_21, 1, 40, :_reduce_22, 1, 40, :_reduce_23, 2, 41, :_reduce_24, 2, 41, :_reduce_25, 1, 41, :_reduce_26, 1, 41, :_reduce_27, 2, 39, :_reduce_none, 4, 39, :_reduce_29, 4, 39, :_reduce_30, 2, 43, :_reduce_31, 4, 43, :_reduce_32, 1, 44, :_reduce_33, 3, 44, :_reduce_34, 1, 45, :_reduce_none, 3, 45, :_reduce_36, 3, 45, :_reduce_37, 2, 46, :_reduce_38, 2, 46, :_reduce_39, 1, 46, :_reduce_40, 1, 46, :_reduce_41, 1, 47, :_reduce_none, 2, 51, :_reduce_43, 1, 51, :_reduce_44, 2, 53, :_reduce_45, 1, 53, :_reduce_46, 1, 50, :_reduce_none, 1, 50, :_reduce_none, 1, 50, :_reduce_none, 1, 50, :_reduce_none, 1, 50, :_reduce_none, 1, 50, :_reduce_none, 1, 54, :_reduce_none, 1, 54, :_reduce_none, 1, 55, :_reduce_none, 1, 55, :_reduce_none, 1, 56, :_reduce_57, 1, 52, :_reduce_58, 1, 57, :_reduce_59, 2, 58, :_reduce_60, 1, 58, :_reduce_none, 2, 49, :_reduce_62, 1, 49, :_reduce_none, 2, 48, :_reduce_64, 1, 48, :_reduce_none, 1, 60, :_reduce_none, 1, 60, :_reduce_none, 1, 60, :_reduce_none, 1, 60, :_reduce_none, 1, 60, :_reduce_none, 1, 62, :_reduce_none, 1, 62, :_reduce_none, 1, 59, :_reduce_none, 1, 59, :_reduce_none, 1, 61, :_reduce_none, 1, 61, :_reduce_none, 1, 61, :_reduce_none, 2, 42, :_reduce_78, 1, 42, :_reduce_none, 1, 63, :_reduce_none, 2, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 1, 63, :_reduce_none, 3, 36, :_reduce_101, 3, 37, :_reduce_102, 1, 65, :_reduce_none, 1, 65, :_reduce_none, 1, 65, :_reduce_none, 1, 65, :_reduce_none, 1, 65, :_reduce_none, 1, 65, :_reduce_none, 2, 66, :_reduce_109, 1, 66, :_reduce_none, 1, 38, :_reduce_111, 1, 67, :_reduce_none, 2, 67, :_reduce_113, 2, 67, :_reduce_114, 2, 67, :_reduce_115, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 1, 68, :_reduce_none, 2, 64, :_reduce_136, 1, 64, :_reduce_none ] racc_reduce_n = 138 racc_shift_n = 179 racc_token_table = { false => 0, :error => 1, :EX_LOW => 2, :QUOTE => 3, :BAR => 4, :SLASH => 5, :BACK_SLASH => 6, :URL => 7, :OTHER => 8, :REF_OPEN => 9, :FOOTNOTE_OPEN => 10, :FOOTNOTE_CLOSE => 11, :EX_HIGH => 12, :EM_OPEN => 13, :EM_CLOSE => 14, :CODE_OPEN => 15, :CODE_CLOSE => 16, :VAR_OPEN => 17, :VAR_CLOSE => 18, :KBD_OPEN => 19, :KBD_CLOSE => 20, :INDEX_OPEN => 21, :INDEX_CLOSE => 22, :REF_CLOSE => 23, :VERB_OPEN => 24, :VERB_CLOSE => 25 } racc_nt_base = 26 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 ] Racc_token_to_s_table = [ "$end", "error", "EX_LOW", "QUOTE", "BAR", "SLASH", "BACK_SLASH", "URL", "OTHER", "REF_OPEN", "FOOTNOTE_OPEN", "FOOTNOTE_CLOSE", "EX_HIGH", "EM_OPEN", "EM_CLOSE", "CODE_OPEN", "CODE_CLOSE", "VAR_OPEN", "VAR_CLOSE", "KBD_OPEN", "KBD_CLOSE", "INDEX_OPEN", "INDEX_CLOSE", "REF_CLOSE", "VERB_OPEN", "VERB_CLOSE", "$start", "content", "elements", "element", "emphasis", "code", "var", "keyboard", "index", "reference", "footnote", "verb", "normal_str_ele", "substitute", "ref_label", "ref_label2", "ref_url_strings", "filename", "element_label", "element_label2", "ref_subst_content", "ref_subst_content_q", "ref_subst_strings_q", "ref_subst_strings_first", "ref_subst_ele2", "ref_subst_eles", "ref_subst_str_ele_first", "ref_subst_eles_q", "ref_subst_ele", "ref_subst_ele_q", "ref_subst_str_ele", "ref_subst_str_ele_q", "ref_subst_strings", "ref_subst_string3", "ref_subst_string", "ref_subst_string_q", "ref_subst_string2", "ref_url_string", "verb_strings", "normal_string", "normal_strings", "verb_string", "verb_normal_string" ] Racc_debug_parser = false ##### State transition tables end ##### # reduce 0 omitted # reduce 1 omitted def _reduce_2(val, _values, result) result.append val[1] result end def _reduce_3(val, _values, result) result = val[0] result end # reduce 4 omitted # reduce 5 omitted # reduce 6 omitted # reduce 7 omitted # reduce 8 omitted # reduce 9 omitted # reduce 10 omitted # reduce 11 omitted # reduce 12 omitted def _reduce_13(val, _values, result) content = val[1] result = inline "#{content}", content result end def _reduce_14(val, _values, result) content = val[1] result = inline "#{content}", content result end def _reduce_15(val, _values, result) content = val[1] result = inline "+#{content}+", content result end def _reduce_16(val, _values, result) content = val[1] result = inline "#{content}", content result end def _reduce_17(val, _values, result) label = val[1] @block_parser.add_label label.reference result = "#{label}" result end def _reduce_18(val, _values, result) result = "{#{val[1]}}[#{val[2].join}]" result end def _reduce_19(val, _values, result) scheme, inline = val[1] result = "{#{inline}}[#{scheme}#{inline.reference}]" result end def _reduce_20(val, _values, result) result = [nil, inline(val[1])] result end def _reduce_21(val, _values, result) result = [ 'rdoc-label:', inline("#{val[0].reference}/#{val[1].reference}") ] result end def _reduce_22(val, _values, result) result = ['rdoc-label:', val[0].reference] result end def _reduce_23(val, _values, result) result = ['rdoc-label:', "#{val[0].reference}/"] result end def _reduce_24(val, _values, result) result = [nil, inline(val[1])] result end def _reduce_25(val, _values, result) result = [ 'rdoc-label:', inline("#{val[0].reference}/#{val[1].reference}") ] result end def _reduce_26(val, _values, result) result = ['rdoc-label:', val[0]] result end def _reduce_27(val, _values, result) ref = val[0].reference result = ['rdoc-label:', inline(ref, "#{ref}/")] result end # reduce 28 omitted def _reduce_29(val, _values, result) result = val[1] result end def _reduce_30(val, _values, result) result = val[1] result end def _reduce_31(val, _values, result) result = inline val[0] result end def _reduce_32(val, _values, result) result = inline "\"#{val[1]}\"" result end def _reduce_33(val, _values, result) result = inline val[0] result end def _reduce_34(val, _values, result) result = inline "\"#{val[1]}\"" result end # reduce 35 omitted def _reduce_36(val, _values, result) result = val[1] result end def _reduce_37(val, _values, result) result = inline val[1] result end def _reduce_38(val, _values, result) result = val[0].append val[1] result end def _reduce_39(val, _values, result) result = val[0].append val[1] result end def _reduce_40(val, _values, result) result = val[0] result end def _reduce_41(val, _values, result) result = inline val[0] result end # reduce 42 omitted def _reduce_43(val, _values, result) result = val[0].append val[1] result end def _reduce_44(val, _values, result) result = inline val[0] result end def _reduce_45(val, _values, result) result = val[0].append val[1] result end def _reduce_46(val, _values, result) result = val[0] result end # reduce 47 omitted # reduce 48 omitted # reduce 49 omitted # reduce 50 omitted # reduce 51 omitted # reduce 52 omitted # reduce 53 omitted # reduce 54 omitted # reduce 55 omitted # reduce 56 omitted def _reduce_57(val, _values, result) result = val[0] result end def _reduce_58(val, _values, result) result = inline val[0] result end def _reduce_59(val, _values, result) result = inline val[0] result end def _reduce_60(val, _values, result) result << val[1] result end # reduce 61 omitted def _reduce_62(val, _values, result) result << val[1] result end # reduce 63 omitted def _reduce_64(val, _values, result) result << val[1] result end # reduce 65 omitted # reduce 66 omitted # reduce 67 omitted # reduce 68 omitted # reduce 69 omitted # reduce 70 omitted # reduce 71 omitted # reduce 72 omitted # reduce 73 omitted # reduce 74 omitted # reduce 75 omitted # reduce 76 omitted # reduce 77 omitted def _reduce_78(val, _values, result) result << val[1] result end # reduce 79 omitted # reduce 80 omitted # reduce 81 omitted # reduce 82 omitted # reduce 83 omitted # reduce 84 omitted # reduce 85 omitted # reduce 86 omitted # reduce 87 omitted # reduce 88 omitted # reduce 89 omitted # reduce 90 omitted # reduce 91 omitted # reduce 92 omitted # reduce 93 omitted # reduce 94 omitted # reduce 95 omitted # reduce 96 omitted # reduce 97 omitted # reduce 98 omitted # reduce 99 omitted # reduce 100 omitted def _reduce_101(val, _values, result) index = @block_parser.add_footnote val[1].rdoc result = "{*#{index}}[rdoc-label:foottext-#{index}:footmark-#{index}]" result end def _reduce_102(val, _values, result) result = inline "#{val[1]}", val[1] result end # reduce 103 omitted # reduce 104 omitted # reduce 105 omitted # reduce 106 omitted # reduce 107 omitted # reduce 108 omitted def _reduce_109(val, _values, result) result << val[1] result end # reduce 110 omitted def _reduce_111(val, _values, result) result = inline val[0] result end # reduce 112 omitted def _reduce_113(val, _values, result) result = val[1] result end def _reduce_114(val, _values, result) result = val[1] result end def _reduce_115(val, _values, result) result = val[1] result end # 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 def _reduce_136(val, _values, result) result << val[1] result end # reduce 137 omitted def _reduce_none(val, _values, result) val[0] end end # class InlineParser end PK!] rd/inline.rbnu[# frozen_string_literal: true ## # Inline keeps track of markup and labels to create proper links. class RDoc::RD::Inline ## # The text of the reference attr_reader :reference ## # The markup of this reference in RDoc format attr_reader :rdoc ## # Creates a new Inline for +rdoc+ and +reference+. # # +rdoc+ may be another Inline or a String. If +reference+ is not given it # will use the text from +rdoc+. def self.new rdoc, reference = rdoc if self === rdoc and reference.equal? rdoc then rdoc else super end end ## # Initializes the Inline with +rdoc+ and +inline+ def initialize rdoc, reference # :not-new: @reference = reference.equal?(rdoc) ? reference.dup : reference # unpack @reference = @reference.reference if self.class === @reference @rdoc = rdoc end def == other # :nodoc: self.class === other and @reference == other.reference and @rdoc == other.rdoc end ## # Appends +more+ to this inline. +more+ may be a String or another Inline. def append more case more when String then @reference += more @rdoc += more when RDoc::RD::Inline then @reference += more.reference @rdoc += more.rdoc else raise "unknown thingy #{more}" end self end def inspect # :nodoc: "(inline: #{self})" end alias to_s rdoc # :nodoc: end PK!('Y'Yrd/block_parser.rbnu[# frozen_string_literal: true # # DO NOT MODIFY!!!! # This file is automatically generated by Racc 1.6.0 # from Racc grammar file "". # require 'racc/parser.rb' class RDoc::RD ## # RD format parser for headings, paragraphs, lists, verbatim sections that # exist as blocks. class BlockParser < Racc::Parser # :stopdoc: MARK_TO_LEVEL = { '=' => 1, '==' => 2, '===' => 3, '====' => 4, '+' => 5, '++' => 6, } # :startdoc: ## # Footnotes for this document attr_reader :footnotes ## # Labels for items in this document attr_reader :labels ## # Path to find included files in attr_accessor :include_path ## # Creates a new RDoc::RD::BlockParser. Use #parse to parse an rd-format # document. def initialize @inline_parser = RDoc::RD::InlineParser.new self @include_path = [] # for testing @footnotes = [] @labels = {} end ## # Parses +src+ and returns an RDoc::Markup::Document. def parse src @src = src @src.push false @footnotes = [] @labels = {} # @i: index(line no.) of src @i = 0 # stack for current indentation @indent_stack = [] # how indented. @current_indent = @indent_stack.join("") # RDoc::RD::BlockParser for tmp src @subparser = nil # which part is in now @in_part = nil @part_content = [] @in_verbatim = false @yydebug = true document = do_parse unless @footnotes.empty? then blankline = document.parts.pop document.parts << RDoc::Markup::Rule.new(1) document.parts.concat @footnotes document.parts.push blankline end document end ## # Returns the next token from the document def next_token # :nodoc: # preprocessing # if it is not in RD part # => method while @in_part != "rd" line = @src[@i] @i += 1 # next line case line # src end when false return [false, false] # RD part begin when /^=begin\s*(?:\bRD\b.*)?\s*$/ if @in_part # if in non-RD part @part_content.push(line) else @in_part = "rd" return [:WHITELINE, "=begin\n"] # <= for textblockand end # non-RD part begin when /^=begin\s+(\w+)/ part = $1 =begin # not imported to RDoc if @in_part # if in non-RD part @part_content.push(line) else @in_part = part if @tree.filter[part] # if filter exists # p "BEGIN_PART: #{@in_part}" # DEBUG end =end @in_part = part # non-RD part end when /^=end(?:$|[\s\0\C-d\C-z])/ if @in_part # if in non-RD part =begin # not imported to RDoc # p "END_PART: #{@in_part}" # DEBUG # make Part-in object part = RDoc::RD::Part.new(@part_content.join(""), @tree, "r") @part_content.clear # call filter, part_out is output(Part object) part_out = @tree.filter[@in_part].call(part) if @tree.filter[@in_part].mode == :rd # if output is RD formatted subtree = parse_subtree(part_out.to_a) else # if output is target formatted basename = Tempfile.create(["rdtmp", ".#{@in_part}"], @tree.tmp_dir) do |tmpfile| tmpfile.print(part_out) File.basename(tmpfile.path) end subtree = parse_subtree(["=begin\n", "<<< #{basename}\n", "=end\n"]) end @in_part = nil return [:SUBTREE, subtree] =end end else =begin # not imported to RDoc if @in_part # if in non-RD part @part_content.push(line) end =end end end @current_indent = @indent_stack.join("") line = @src[@i] case line when false if_current_indent_equal("") do [false, false] end when /^=end/ if_current_indent_equal("") do @in_part = nil [:WHITELINE, "=end"] # MUST CHANGE?? end when /^\s*$/ @i += 1 # next line return [:WHITELINE, ':WHITELINE'] when /^\#/ # comment line @i += 1 # next line self.next_token() when /^(={1,4})(?!=)\s*(?=\S)/, /^(\+{1,2})(?!\+)\s*(?=\S)/ rest = $' # ' rest.strip! mark = $1 if_current_indent_equal("") do return [:HEADLINE, [MARK_TO_LEVEL[mark], rest]] end when /^<<<\s*(\S+)/ file = $1 if_current_indent_equal("") do suffix = file[-3 .. -1] if suffix == ".rd" or suffix == ".rb" subtree = parse_subtree(get_included(file)) [:SUBTREE, subtree] else [:INCLUDE, file] end end when /^(\s*)\*(\s*)/ rest = $' # ' newIndent = $2 if_current_indent_equal($1) do if @in_verbatim [:STRINGLINE, line] else @indent_stack.push("\s" + newIndent) [:ITEMLISTLINE, rest] end end when /^(\s*)(\(\d+\))(\s*)/ rest = $' # ' mark = $2 newIndent = $3 if_current_indent_equal($1) do if @in_verbatim [:STRINGLINE, line] else @indent_stack.push("\s" * mark.size + newIndent) [:ENUMLISTLINE, rest] end end when /^(\s*):(\s*)/ rest = $' # ' newIndent = $2 if_current_indent_equal($1) do if @in_verbatim [:STRINGLINE, line] else @indent_stack.push("\s#{$2}") [:DESCLISTLINE, rest] end end when /^(\s*)---(?!-|\s*$)/ indent = $1 rest = $' /\s*/ === rest term = $' new_indent = $& if_current_indent_equal(indent) do if @in_verbatim [:STRINGLINE, line] else @indent_stack.push("\s\s\s" + new_indent) [:METHODLISTLINE, term] end end when /^(\s*)/ if_current_indent_equal($1) do [:STRINGLINE, line] end else raise "[BUG] parsing error may occurred." end end ## # Yields to the given block if +indent+ matches the current indent, otherwise # an indentation token is processed. def if_current_indent_equal(indent) indent = indent.sub(/\t/, "\s" * 8) if @current_indent == indent @i += 1 # next line yield elsif indent.index(@current_indent) == 0 @indent_stack.push(indent[@current_indent.size .. -1]) [:INDENT, ":INDENT"] else @indent_stack.pop [:DEDENT, ":DEDENT"] end end private :if_current_indent_equal ## # Cuts off excess whitespace in +src+ def cut_off(src) ret = [] whiteline_buf = [] line = src.shift /^\s*/ =~ line indent = Regexp.quote($&) ret.push($') while line = src.shift if /^(\s*)$/ =~ line whiteline_buf.push(line) elsif /^#{indent}/ =~ line unless whiteline_buf.empty? ret.concat(whiteline_buf) whiteline_buf.clear end ret.push($') else raise "[BUG]: probably Parser Error while cutting off.\n" end end ret end private :cut_off def set_term_to_element(parent, term) # parent.set_term_under_document_struct(term, @tree.document_struct) parent.set_term_without_document_struct(term) end private :set_term_to_element ## # Raises a ParseError when invalid formatting is found def on_error(et, ev, _values) prv, cur, nxt = format_line_num(@i, @i+1, @i+2) raise ParseError, <|#{@src[@i].chomp} #{nxt} |#{@src[@i+1].chomp} Msg end ## # Current line number def line_index @i end ## # Parses subtree +src+ def parse_subtree src @subparser ||= RDoc::RD::BlockParser.new @subparser.parse src end private :parse_subtree ## # Retrieves the content for +file+ from the include_path def get_included(file) included = [] @include_path.each do |dir| file_name = File.join dir, file if File.exist? file_name then included = IO.readlines file_name break end end included end private :get_included ## # Formats line numbers +line_numbers+ prettily def format_line_num(*line_numbers) width = line_numbers.collect{|i| i.to_s.length }.max line_numbers.collect{|i| sprintf("%#{width}d", i) } end private :format_line_num ## # Retrieves the content of +values+ as a single String def content values values.map { |value| value.content }.join end ## # Creates a paragraph for +value+ def paragraph value content = cut_off(value).join(' ').rstrip contents = @inline_parser.parse content RDoc::Markup::Paragraph.new(*contents) end ## # Adds footnote +content+ to the document def add_footnote content index = @footnotes.length / 2 + 1 footmark_link = "{^#{index}}[rdoc-label:footmark-#{index}:foottext-#{index}]" @footnotes << RDoc::Markup::Paragraph.new(footmark_link, ' ', *content) @footnotes << RDoc::Markup::BlankLine.new index end ## # Adds label +label+ to the document def add_label label @labels[label] = true label end # :stopdoc: ##### State transition tables begin ### racc_action_table = [ 34, 35, 30, 33, 40, 34, 35, 30, 33, 40, 65, 34, 35, 30, 33, 14, 73, 36, 38, 34, 15, 88, 34, 35, 30, 33, 14, 9, 10, 11, 12, 15, 34, 35, 30, 33, 14, 9, 10, 11, 12, 15, 34, 35, 30, 33, 35, 47, 30, 54, 33, 15, 34, 35, 30, 33, 54, 47, 14, 14, 59, 15, 34, 35, 30, 33, 14, 73, 67, 76, 77, 15, 34, 35, 30, 33, 14, 73, 54, 81, 38, 15, 34, 35, 30, 33, 14, 73, 38, 40, 83, 15, 34, 35, 30, 33, 14, 73, nil, nil, nil, 15, 34, 35, 30, 33, 14, 73, nil, nil, nil, 15, 34, 35, 30, 33, 14, 73, nil, nil, nil, 15, 34, 35, 30, 33, 14, 73, nil, nil, nil, 15, 34, 35, 30, 33, 14, 73, nil, nil, nil, 15, 34, 35, 30, 33, 14, 73, 61, 63, nil, 15, 14, 62, 60, 61, 63, 79, 61, 63, 62, 87, nil, 62, 34, 35, 30, 33 ] racc_action_check = [ 41, 41, 41, 41, 41, 15, 15, 15, 15, 15, 41, 86, 86, 86, 86, 86, 86, 1, 13, 22, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 24, 24, 24, 24, 25, 24, 28, 30, 31, 24, 27, 27, 27, 27, 33, 27, 34, 35, 36, 27, 45, 45, 45, 45, 45, 45, 44, 49, 51, 45, 46, 46, 46, 46, 46, 46, 54, 56, 57, 46, 47, 47, 47, 47, 47, 47, 58, 62, 66, 47, 68, 68, 68, 68, 68, 68, nil, nil, nil, 68, 74, 74, 74, 74, 74, 74, nil, nil, nil, 74, 75, 75, 75, 75, 75, 75, nil, nil, nil, 75, 78, 78, 78, 78, 78, 78, nil, nil, nil, 78, 79, 79, 79, 79, 79, 79, nil, nil, nil, 79, 85, 85, 85, 85, 85, 85, 39, 39, nil, 85, 52, 39, 39, 82, 82, 52, 64, 64, 82, 82, nil, 64, 20, 20, 20, 20 ] racc_action_pointer = [ 19, 17, 29, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, 11, nil, 2, nil, nil, nil, nil, 161, nil, 16, nil, 39, 42, nil, 49, 43, nil, 41, 44, nil, 48, 51, 52, 60, nil, nil, 141, nil, -3, nil, nil, 55, 59, 69, 79, nil, 56, nil, 57, 145, nil, 70, nil, 66, 73, 81, nil, nil, nil, 82, nil, 151, nil, 77, nil, 89, nil, nil, nil, nil, nil, 99, 109, nil, nil, 119, 129, nil, nil, 148, nil, nil, 139, 8, nil, nil ] racc_action_default = [ -2, -73, -1, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -16, -73, -23, -24, -25, -26, -27, -31, -32, -34, -72, -36, -38, -72, -40, -42, -59, -44, -46, -59, -63, -65, -73, -3, -15, -73, -22, -73, -30, -33, -73, -69, -70, -71, -37, -73, -41, -73, -51, -58, -61, -45, -73, -62, -64, 89, -17, -19, -73, -21, -18, -28, -73, -35, -66, -53, -54, -55, -56, -57, -67, -68, -39, -43, -49, -73, -60, -47, -73, -29, -52, -48, -73, -20, -50 ] racc_goto_table = [ 4, 39, 4, 68, 74, 75, 5, 6, 5, 6, 44, 42, 51, 49, 3, 56, 37, 57, 58, 1, 2, 66, 84, 41, 43, 48, 50, 64, 84, 84, 45, 46, 42, 45, 46, 55, 85, 86, 80, 84, 84, nil, nil, nil, nil, nil, nil, nil, 82, nil, nil, nil, 78 ] racc_goto_check = [ 4, 10, 4, 31, 31, 31, 5, 6, 5, 6, 21, 12, 27, 21, 3, 27, 3, 9, 9, 1, 2, 11, 32, 17, 19, 23, 26, 10, 32, 32, 5, 6, 12, 5, 6, 29, 31, 31, 33, 32, 32, nil, nil, nil, nil, nil, nil, nil, 10, nil, nil, nil, 4 ] racc_goto_pointer = [ nil, 19, 20, 14, 0, 6, 7, nil, nil, -17, -14, -20, -9, nil, nil, nil, nil, 8, nil, 2, nil, -14, nil, 0, nil, nil, -2, -18, nil, 4, nil, -42, -46, -16 ] racc_goto_default = [ nil, nil, nil, nil, 70, 71, 72, 7, 8, 13, nil, nil, 21, 16, 17, 18, 19, 20, 22, 23, 24, nil, 25, 26, 27, 28, 29, nil, 31, 32, 52, nil, 69, 53 ] racc_reduce_table = [ 0, 0, :racc_error, 1, 15, :_reduce_1, 0, 15, :_reduce_2, 2, 16, :_reduce_3, 1, 16, :_reduce_4, 1, 17, :_reduce_5, 1, 17, :_reduce_6, 1, 17, :_reduce_none, 1, 17, :_reduce_8, 1, 17, :_reduce_9, 1, 17, :_reduce_10, 1, 17, :_reduce_11, 1, 21, :_reduce_12, 1, 22, :_reduce_13, 1, 18, :_reduce_14, 2, 23, :_reduce_15, 1, 23, :_reduce_16, 3, 19, :_reduce_17, 1, 25, :_reduce_18, 2, 24, :_reduce_19, 4, 24, :_reduce_20, 2, 24, :_reduce_21, 1, 24, :_reduce_22, 1, 26, :_reduce_none, 1, 26, :_reduce_none, 1, 26, :_reduce_none, 1, 26, :_reduce_none, 1, 20, :_reduce_27, 3, 20, :_reduce_28, 4, 20, :_reduce_29, 2, 31, :_reduce_30, 1, 31, :_reduce_31, 1, 27, :_reduce_32, 2, 32, :_reduce_33, 1, 32, :_reduce_34, 3, 33, :_reduce_35, 1, 28, :_reduce_36, 2, 36, :_reduce_37, 1, 36, :_reduce_38, 3, 37, :_reduce_39, 1, 29, :_reduce_40, 2, 39, :_reduce_41, 1, 39, :_reduce_42, 3, 40, :_reduce_43, 1, 30, :_reduce_44, 2, 42, :_reduce_45, 1, 42, :_reduce_46, 3, 43, :_reduce_47, 3, 41, :_reduce_48, 2, 41, :_reduce_49, 4, 41, :_reduce_50, 1, 41, :_reduce_51, 2, 45, :_reduce_52, 1, 45, :_reduce_none, 1, 46, :_reduce_54, 1, 46, :_reduce_55, 1, 46, :_reduce_none, 1, 46, :_reduce_57, 1, 44, :_reduce_none, 0, 44, :_reduce_none, 2, 47, :_reduce_none, 1, 47, :_reduce_none, 2, 34, :_reduce_62, 1, 34, :_reduce_63, 2, 38, :_reduce_64, 1, 38, :_reduce_65, 2, 35, :_reduce_66, 2, 35, :_reduce_67, 2, 35, :_reduce_68, 1, 35, :_reduce_69, 1, 35, :_reduce_none, 1, 35, :_reduce_71, 0, 35, :_reduce_72 ] racc_reduce_n = 73 racc_shift_n = 89 racc_token_table = { false => 0, :error => 1, :DUMMY => 2, :ITEMLISTLINE => 3, :ENUMLISTLINE => 4, :DESCLISTLINE => 5, :METHODLISTLINE => 6, :STRINGLINE => 7, :WHITELINE => 8, :SUBTREE => 9, :HEADLINE => 10, :INCLUDE => 11, :INDENT => 12, :DEDENT => 13 } racc_nt_base = 14 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 ] Racc_token_to_s_table = [ "$end", "error", "DUMMY", "ITEMLISTLINE", "ENUMLISTLINE", "DESCLISTLINE", "METHODLISTLINE", "STRINGLINE", "WHITELINE", "SUBTREE", "HEADLINE", "INCLUDE", "INDENT", "DEDENT", "$start", "document", "blocks", "block", "textblock", "verbatim", "lists", "headline", "include", "textblockcontent", "verbatimcontent", "verbatim_after_lists", "list", "itemlist", "enumlist", "desclist", "methodlist", "lists2", "itemlistitems", "itemlistitem", "first_textblock_in_itemlist", "other_blocks_in_list", "enumlistitems", "enumlistitem", "first_textblock_in_enumlist", "desclistitems", "desclistitem", "description_part", "methodlistitems", "methodlistitem", "whitelines", "blocks_in_list", "block_in_list", "whitelines2" ] Racc_debug_parser = false ##### State transition tables end ##### # reduce 0 omitted def _reduce_1(val, _values, result) result = RDoc::Markup::Document.new(*val[0]) result end def _reduce_2(val, _values, result) raise ParseError, "file empty" result end def _reduce_3(val, _values, result) result = val[0].concat val[1] result end def _reduce_4(val, _values, result) result = val[0] result end def _reduce_5(val, _values, result) result = val result end def _reduce_6(val, _values, result) result = val result end # reduce 7 omitted def _reduce_8(val, _values, result) result = val result end def _reduce_9(val, _values, result) result = val result end def _reduce_10(val, _values, result) result = [RDoc::Markup::BlankLine.new] result end def _reduce_11(val, _values, result) result = val[0].parts result end def _reduce_12(val, _values, result) # val[0] is like [level, title] title = @inline_parser.parse(val[0][1]) result = RDoc::Markup::Heading.new(val[0][0], title) result end def _reduce_13(val, _values, result) result = RDoc::Markup::Include.new val[0], @include_path result end def _reduce_14(val, _values, result) # val[0] is Array of String result = paragraph val[0] result end def _reduce_15(val, _values, result) result << val[1].rstrip result end def _reduce_16(val, _values, result) result = [val[0].rstrip] result end def _reduce_17(val, _values, result) # val[1] is Array of String content = cut_off val[1] result = RDoc::Markup::Verbatim.new(*content) # imform to lexer. @in_verbatim = false result end def _reduce_18(val, _values, result) # val[0] is Array of String content = cut_off val[0] result = RDoc::Markup::Verbatim.new(*content) # imform to lexer. @in_verbatim = false result end def _reduce_19(val, _values, result) result << val[1] result end def _reduce_20(val, _values, result) result.concat val[2] result end def _reduce_21(val, _values, result) result << "\n" result end def _reduce_22(val, _values, result) result = val # inform to lexer. @in_verbatim = true result end # reduce 23 omitted # reduce 24 omitted # reduce 25 omitted # reduce 26 omitted def _reduce_27(val, _values, result) result = val[0] result end def _reduce_28(val, _values, result) result = val[1] result end def _reduce_29(val, _values, result) result = val[1].push(val[2]) result end def _reduce_30(val, _values, result) result = val[0] << val[1] result end def _reduce_31(val, _values, result) result = [val[0]] result end def _reduce_32(val, _values, result) result = RDoc::Markup::List.new :BULLET, *val[0] result end def _reduce_33(val, _values, result) result.push(val[1]) result end def _reduce_34(val, _values, result) result = val result end def _reduce_35(val, _values, result) result = RDoc::Markup::ListItem.new nil, val[0], *val[1] result end def _reduce_36(val, _values, result) result = RDoc::Markup::List.new :NUMBER, *val[0] result end def _reduce_37(val, _values, result) result.push(val[1]) result end def _reduce_38(val, _values, result) result = val result end def _reduce_39(val, _values, result) result = RDoc::Markup::ListItem.new nil, val[0], *val[1] result end def _reduce_40(val, _values, result) result = RDoc::Markup::List.new :NOTE, *val[0] result end def _reduce_41(val, _values, result) result.push(val[1]) result end def _reduce_42(val, _values, result) result = val result end def _reduce_43(val, _values, result) term = @inline_parser.parse val[0].strip result = RDoc::Markup::ListItem.new term, *val[1] result end def _reduce_44(val, _values, result) result = RDoc::Markup::List.new :LABEL, *val[0] result end def _reduce_45(val, _values, result) result.push(val[1]) result end def _reduce_46(val, _values, result) result = val result end def _reduce_47(val, _values, result) result = RDoc::Markup::ListItem.new "#{val[0].strip}", *val[1] result end def _reduce_48(val, _values, result) result = [val[1]].concat(val[2]) result end def _reduce_49(val, _values, result) result = [val[1]] result end def _reduce_50(val, _values, result) result = val[2] result end def _reduce_51(val, _values, result) result = [] result end def _reduce_52(val, _values, result) result.concat val[1] result end # reduce 53 omitted def _reduce_54(val, _values, result) result = val result end def _reduce_55(val, _values, result) result = val result end # reduce 56 omitted def _reduce_57(val, _values, result) result = [] result end # reduce 58 omitted # reduce 59 omitted # reduce 60 omitted # reduce 61 omitted def _reduce_62(val, _values, result) result = paragraph [val[0]].concat(val[1]) result end def _reduce_63(val, _values, result) result = paragraph [val[0]] result end def _reduce_64(val, _values, result) result = paragraph [val[0]].concat(val[1]) result end def _reduce_65(val, _values, result) result = paragraph [val[0]] result end def _reduce_66(val, _values, result) result = [val[0]].concat(val[1]) result end def _reduce_67(val, _values, result) result.concat val[1] result end def _reduce_68(val, _values, result) result = val[1] result end def _reduce_69(val, _values, result) result = val result end # reduce 70 omitted def _reduce_71(val, _values, result) result = [] result end def _reduce_72(val, _values, result) result = [] result end def _reduce_none(val, _values, result) val[0] end end # class BlockParser end PK!. ;m known_classes.rbnu[# frozen_string_literal: true module RDoc ## # Ruby's built-in classes, modules and exceptions KNOWN_CLASSES = { "rb_cArray" => "Array", "rb_cBasicObject" => "BasicObject", "rb_cBignum" => "Bignum", "rb_cClass" => "Class", "rb_cData" => "Data", "rb_cDir" => "Dir", "rb_cEncoding" => "Encoding", "rb_cFalseClass" => "FalseClass", "rb_cFile" => "File", "rb_cFixnum" => "Fixnum", "rb_cFloat" => "Float", "rb_cHash" => "Hash", "rb_cIO" => "IO", "rb_cInteger" => "Integer", "rb_cModule" => "Module", "rb_cNilClass" => "NilClass", "rb_cNumeric" => "Numeric", "rb_cObject" => "Object", "rb_cProc" => "Proc", "rb_cRange" => "Range", "rb_cRefinement" => "Refinement", "rb_cRegexp" => "Regexp", "rb_cRubyVM" => "RubyVM", "rb_cSocket" => "Socket", "rb_cString" => "String", "rb_cStruct" => "Struct", "rb_cSymbol" => "Symbol", "rb_cThread" => "Thread", "rb_cTime" => "Time", "rb_cTrueClass" => "TrueClass", "rb_eArgError" => "ArgumentError", "rb_eEOFError" => "EOFError", "rb_eException" => "Exception", "rb_eFatal" => "fatal", "rb_eFloatDomainError" => "FloatDomainError", "rb_eIOError" => "IOError", "rb_eIndexError" => "IndexError", "rb_eInterrupt" => "Interrupt", "rb_eLoadError" => "LoadError", "rb_eNameError" => "NameError", "rb_eNoMemError" => "NoMemoryError", "rb_eNotImpError" => "NotImplementedError", "rb_eRangeError" => "RangeError", "rb_eRuntimeError" => "RuntimeError", "rb_eScriptError" => "ScriptError", "rb_eSecurityError" => "SecurityError", "rb_eSignal" => "SignalException", "rb_eStandardError" => "StandardError", "rb_eSyntaxError" => "SyntaxError", "rb_eSystemCallError" => "SystemCallError", "rb_eSystemExit" => "SystemExit", "rb_eTypeError" => "TypeError", "rb_eZeroDivError" => "ZeroDivisionError", "rb_mComparable" => "Comparable", "rb_mEnumerable" => "Enumerable", "rb_mErrno" => "Errno", "rb_mFConst" => "File::Constants", "rb_mFileTest" => "FileTest", "rb_mGC" => "GC", "rb_mKernel" => "Kernel", "rb_mMath" => "Math", "rb_mProcess" => "Process" } end PK!n== ri/task.rbnu[# frozen_string_literal: true begin gem 'rdoc' rescue Gem::LoadError end unless defined?(RDoc) require_relative '../task' ## # RDoc::RI::Task creates ri data in ./.rdoc for your project. # # It contains the following tasks: # # [ri] # Build ri data # # [clobber_ri] # Delete ri data files. This target is automatically added to the main # clobber target. # # [reri] # Rebuild the ri data from scratch even if they are not out of date. # # Simple example: # # require 'rdoc/ri/task' # # RDoc::RI::Task.new do |ri| # ri.main = 'README.rdoc' # ri.rdoc_files.include 'README.rdoc', 'lib/**/*.rb' # end # # For further configuration details see RDoc::Task. class RDoc::RI::Task < RDoc::Task DEFAULT_NAMES = { # :nodoc: :clobber_rdoc => :clobber_ri, :rdoc => :ri, :rerdoc => :reri, } ## # Create an ri task with the given name. See RDoc::Task for documentation on # setting names. def initialize name = DEFAULT_NAMES # :yield: self super end def clobber_task_description # :nodoc: "Remove RI data files" end ## # Sets default task values def defaults super @rdoc_dir = '.rdoc' end def rdoc_task_description # :nodoc: 'Build RI data files' end def rerdoc_task_description # :nodoc: 'Rebuild RI data files' end end PK!tUU ri/store.rbnu[# frozen_string_literal: true module RDoc::RI Store = RDoc::Store # :nodoc: end PK!Vnrrri/formatter.rbnu[# frozen_string_literal: true ## # For RubyGems backwards compatibility module RDoc::RI::Formatter # :nodoc: end PK! Ų^^ ri/paths.rbnu[# frozen_string_literal: true require_relative '../rdoc' ## # The directories where ri data lives. Paths can be enumerated via ::each, or # queried individually via ::system_dir, ::site_dir, ::home_dir and ::gem_dir. module RDoc::RI::Paths #:stopdoc: require 'rbconfig' version = RbConfig::CONFIG['ruby_version_dir_name'] || RbConfig::CONFIG['ruby_version'] BASE = File.join RbConfig::CONFIG['ridir'], version HOMEDIR = RDoc.home #:startdoc: ## # Iterates over each selected path yielding the directory and type. # # Yielded types: # :system:: Where Ruby's ri data is stored. Yielded when +system+ is # true # :site:: Where ri for installed libraries are stored. Yielded when # +site+ is true. Normally no ri data is stored here. # :home:: ~/.rdoc. Yielded when +home+ is true. # :gem:: ri data for an installed gem. Yielded when +gems+ is true. # :extra:: ri data directory from the command line. Yielded for each # entry in +extra_dirs+ def self.each system = true, site = true, home = true, gems = :latest, *extra_dirs # :yields: directory, type return enum_for __method__, system, site, home, gems, *extra_dirs unless block_given? extra_dirs.each do |dir| yield dir, :extra end yield system_dir, :system if system yield site_dir, :site if site yield home_dir, :home if home and HOMEDIR gemdirs(gems).each do |dir| yield dir, :gem end if gems nil end ## # The ri directory for the gem with +gem_name+. def self.gem_dir name, version req = Gem::Requirement.new "= #{version}" spec = Gem::Specification.find_by_name name, req File.join spec.doc_dir, 'ri' end ## # The latest installed gems' ri directories. +filter+ can be :all or # :latest. # # A +filter+ :all includes all versions of gems and includes gems without # ri documentation. def self.gemdirs filter = :latest ri_paths = {} all = Gem::Specification.map do |spec| [File.join(spec.doc_dir, 'ri'), spec.name, spec.version] end if filter == :all then gemdirs = [] all.group_by do |_, name, _| name end.sort_by do |group, _| group end.map do |group, items| items.sort_by do |_, _, version| version end.reverse_each do |dir,| gemdirs << dir end end return gemdirs end all.each do |dir, name, ver| next unless File.exist? dir if ri_paths[name].nil? or ver > ri_paths[name].first then ri_paths[name] = [ver, name, dir] end end ri_paths.sort_by { |_, (_, name, _)| name }.map { |k, v| v.last } rescue LoadError [] end ## # The location of the rdoc data in the user's home directory. # # Like ::system, ri data in the user's home directory is rare and predates # libraries distributed via RubyGems. ri data is rarely generated into this # directory. def self.home_dir HOMEDIR end ## # Returns existing directories from the selected documentation directories # as an Array. # # See also ::each def self.path(system = true, site = true, home = true, gems = :latest, *extra_dirs) path = raw_path system, site, home, gems, *extra_dirs path.select { |directory| File.directory? directory } end ## # Returns selected documentation directories including nonexistent # directories. # # See also ::each def self.raw_path(system, site, home, gems, *extra_dirs) path = [] each(system, site, home, gems, *extra_dirs) do |dir, type| path << dir end path.compact end ## # The location of ri data installed into the site dir. # # Historically this was available for documentation installed by Ruby # libraries predating RubyGems. It is unlikely to contain any content for # modern Ruby installations. def self.site_dir File.join BASE, 'site' end ## # The location of the built-in ri data. # # This data is built automatically when `make` is run when Ruby is # installed. If you did not install Ruby by hand you may need to install # the documentation yourself. Please consult the documentation for your # package manager or Ruby installer for details. You can also use the # rdoc-data gem to install system ri data for common versions of Ruby. def self.system_dir File.join BASE, 'system' end end PK!=], ri/driver.rbnu[# frozen_string_literal: true require 'optparse' require_relative '../../rdoc' require_relative 'formatter' # For RubyGems backwards compatibility # TODO: Fix weird documentation with `require_relative` ## # The RI driver implements the command-line ri tool. # # The driver supports: # * loading RI data from: # * Ruby's standard library # * RubyGems # * ~/.rdoc # * A user-supplied directory # * Paging output (uses RI_PAGER environment variable, PAGER environment # variable or the less, more and pager programs) # * Interactive mode with tab-completion # * Abbreviated names (ri Zl shows Zlib documentation) # * Colorized output # * Merging output from multiple RI data sources class RDoc::RI::Driver ## # Base Driver error class class Error < RDoc::RI::Error; end ## # Raised when a name isn't found in the ri data stores class NotFoundError < Error def initialize(klass, suggestions = nil) # :nodoc: @klass = klass @suggestions = suggestions end ## # Name that wasn't found def name @klass end def message # :nodoc: str = "Nothing known about #{@klass}" if @suggestions and !@suggestions.empty? str += "\nDid you mean? #{@suggestions.join("\n ")}" end str end end ## # Show all method documentation following a class or module attr_accessor :show_all ## # An RDoc::RI::Store for each entry in the RI path attr_accessor :stores ## # Controls the user of the pager vs $stdout attr_accessor :use_stdout ## # Default options for ri def self.default_options options = {} options[:interactive] = false options[:profile] = false options[:show_all] = false options[:use_stdout] = !$stdout.tty? options[:width] = 72 # By default all standard paths are used. options[:use_system] = true options[:use_site] = true options[:use_home] = true options[:use_gems] = true options[:extra_doc_dirs] = [] return options end ## # Dump +data_path+ using pp def self.dump data_path require 'pp' File.open data_path, 'rb' do |io| pp Marshal.load(io.read) end end ## # Parses +argv+ and returns a Hash of options def self.process_args argv options = default_options opts = OptionParser.new do |opt| opt.accept File do |file,| File.readable?(file) and not File.directory?(file) and file end opt.program_name = File.basename $0 opt.version = RDoc::VERSION opt.release = nil opt.summary_indent = ' ' * 4 opt.banner = <<-EOT Usage: #{opt.program_name} [options] [name ...] Where name can be: Class | Module | Module::Class Class::method | Class#method | Class.method | method gem_name: | gem_name:README | gem_name:History ruby: | ruby:NEWS | ruby:globals All class names may be abbreviated to their minimum unambiguous form. If a name is ambiguous, all valid options will be listed. A '.' matches either class or instance methods, while #method matches only instance and ::method matches only class methods. README and other files may be displayed by prefixing them with the gem name they're contained in. If the gem name is followed by a ':' all files in the gem will be shown. The file name extension may be omitted where it is unambiguous. 'ruby' can be used as a pseudo gem name to display files from the Ruby core documentation. Use 'ruby:' by itself to get a list of all available core documentation files. For example: #{opt.program_name} Fil #{opt.program_name} File #{opt.program_name} File.new #{opt.program_name} zip #{opt.program_name} rdoc:README #{opt.program_name} ruby:comments Note that shell quoting or escaping may be required for method names containing punctuation: #{opt.program_name} 'Array.[]' #{opt.program_name} compact\\! To see the default directories #{opt.program_name} will search, run: #{opt.program_name} --list-doc-dirs Specifying the --system, --site, --home, --gems, or --doc-dir options will limit ri to searching only the specified directories. ri options may be set in the RI environment variable. The ri pager can be set with the RI_PAGER environment variable or the PAGER environment variable. EOT opt.separator nil opt.separator "Options:" opt.separator nil opt.on("--[no-]interactive", "-i", "In interactive mode you can repeatedly", "look up methods with autocomplete.") do |interactive| options[:interactive] = interactive end opt.separator nil opt.on("--[no-]all", "-a", "Show all documentation for a class or", "module.") do |show_all| options[:show_all] = show_all end opt.separator nil opt.on("--[no-]list", "-l", "List classes ri knows about.") do |list| options[:list] = list end opt.separator nil opt.on("--[no-]pager", "Send output to a pager,", "rather than directly to stdout.") do |use_pager| options[:use_stdout] = !use_pager end opt.separator nil opt.on("-T", "Synonym for --no-pager.") do options[:use_stdout] = true end opt.separator nil opt.on("--width=WIDTH", "-w", OptionParser::DecimalInteger, "Set the width of the output.") do |width| options[:width] = width end opt.separator nil opt.on("--server[=PORT]", Integer, "Run RDoc server on the given port.", "The default port is 8214.") do |port| options[:server] = port || 8214 end opt.separator nil formatters = RDoc::Markup.constants.grep(/^To[A-Z][a-z]+$/).sort formatters = formatters.sort.map do |formatter| formatter.to_s.sub('To', '').downcase end formatters -= %w[html label test] # remove useless output formats opt.on("--format=NAME", "-f", "Use the selected formatter. The default", "formatter is bs for paged output and ansi", "otherwise. Valid formatters are:", "#{formatters.join(', ')}.", formatters) do |value| options[:formatter] = RDoc::Markup.const_get "To#{value.capitalize}" end opt.separator nil opt.on("--help", "-h", "Show help and exit.") do puts opts exit end opt.separator nil opt.on("--version", "-v", "Output version information and exit.") do puts "#{opts.program_name} #{opts.version}" exit end opt.separator nil opt.separator "Data source options:" opt.separator nil opt.on("--[no-]list-doc-dirs", "List the directories from which ri will", "source documentation on stdout and exit.") do |list_doc_dirs| options[:list_doc_dirs] = list_doc_dirs end opt.separator nil opt.on("--doc-dir=DIRNAME", "-d", Array, "List of directories from which to source", "documentation in addition to the standard", "directories. May be repeated.") do |value| value.each do |dir| unless File.directory? dir then raise OptionParser::InvalidArgument, "#{dir} is not a directory" end options[:extra_doc_dirs] << File.expand_path(dir) end end opt.separator nil opt.on("--no-standard-docs", "Do not include documentation from", "the Ruby standard library, site_lib,", "installed gems, or ~/.rdoc.", "Use with --doc-dir.") do options[:use_system] = false options[:use_site] = false options[:use_gems] = false options[:use_home] = false end opt.separator nil opt.on("--[no-]system", "Include documentation from Ruby's", "standard library. Defaults to true.") do |value| options[:use_system] = value end opt.separator nil opt.on("--[no-]site", "Include documentation from libraries", "installed in site_lib.", "Defaults to true.") do |value| options[:use_site] = value end opt.separator nil opt.on("--[no-]gems", "Include documentation from RubyGems.", "Defaults to true.") do |value| options[:use_gems] = value end opt.separator nil opt.on("--[no-]home", "Include documentation stored in ~/.rdoc.", "Defaults to true.") do |value| options[:use_home] = value end opt.separator nil opt.separator "Debug options:" opt.separator nil opt.on("--[no-]profile", "Run with the ruby profiler.") do |value| options[:profile] = value end opt.separator nil opt.on("--dump=CACHE", File, "Dump data from an ri cache or data file.") do |value| options[:dump_path] = value end end argv = ENV['RI'].to_s.split(' ').concat argv opts.parse! argv options[:names] = argv options[:use_stdout] ||= !$stdout.tty? options[:use_stdout] ||= options[:interactive] options[:width] ||= 72 options rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e puts opts puts puts e exit 1 end ## # Runs the ri command line executable using +argv+ def self.run argv = ARGV options = process_args argv if options[:dump_path] then dump options[:dump_path] return end ri = new options ri.run end ## # Creates a new driver using +initial_options+ from ::process_args def initialize initial_options = {} @paging = false @classes = nil options = self.class.default_options.update(initial_options) @formatter_klass = options[:formatter] require 'profile' if options[:profile] @names = options[:names] @list = options[:list] @doc_dirs = [] @stores = [] RDoc::RI::Paths.each(options[:use_system], options[:use_site], options[:use_home], options[:use_gems], *options[:extra_doc_dirs]) do |path, type| @doc_dirs << path store = RDoc::RI::Store.new path, type store.load_cache @stores << store end @list_doc_dirs = options[:list_doc_dirs] @interactive = options[:interactive] @server = options[:server] @use_stdout = options[:use_stdout] @show_all = options[:show_all] @width = options[:width] end ## # Adds paths for undocumented classes +also_in+ to +out+ def add_also_in out, also_in return if also_in.empty? out << RDoc::Markup::Rule.new(1) out << RDoc::Markup::Paragraph.new("Also found in:") paths = RDoc::Markup::Verbatim.new also_in.each do |store| paths.parts.push store.friendly_path, "\n" end out << paths end ## # Adds a class header to +out+ for class +name+ which is described in # +classes+. def add_class out, name, classes heading = if classes.all? { |klass| klass.module? } then name else superclass = classes.map do |klass| klass.superclass unless klass.module? end.compact.shift || 'Object' superclass = superclass.full_name unless String === superclass "#{name} < #{superclass}" end out << RDoc::Markup::Heading.new(1, heading) out << RDoc::Markup::BlankLine.new end ## # Adds "(from ...)" to +out+ for +store+ def add_from out, store out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})") end ## # Adds +extends+ to +out+ def add_extends out, extends add_extension_modules out, 'Extended by', extends end ## # Adds a list of +extensions+ to this module of the given +type+ to +out+. # add_includes and add_extends call this, so you should use those directly. def add_extension_modules out, type, extensions return if extensions.empty? out << RDoc::Markup::Rule.new(1) out << RDoc::Markup::Heading.new(1, "#{type}:") extensions.each do |modules, store| if modules.length == 1 then add_extension_modules_single out, store, modules.first else add_extension_modules_multiple out, store, modules end end end ## # Renders multiple included +modules+ from +store+ to +out+. def add_extension_modules_multiple out, store, modules # :nodoc: out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})") wout, with = modules.partition { |incl| incl.comment.empty? } out << RDoc::Markup::BlankLine.new unless with.empty? with.each do |incl| out << RDoc::Markup::Paragraph.new(incl.name) out << RDoc::Markup::BlankLine.new out << incl.comment end unless wout.empty? then verb = RDoc::Markup::Verbatim.new wout.each do |incl| verb.push incl.name, "\n" end out << verb end end ## # Adds a single extension module +include+ from +store+ to +out+ def add_extension_modules_single out, store, include # :nodoc: name = include.name path = store.friendly_path out << RDoc::Markup::Paragraph.new("#{name} (from #{path})") if include.comment then out << RDoc::Markup::BlankLine.new out << include.comment end end ## # Adds +includes+ to +out+ def add_includes out, includes add_extension_modules out, 'Includes', includes end ## # Looks up the method +name+ and adds it to +out+ def add_method out, name filtered = lookup_method name method_out = method_document name, filtered out.concat method_out.parts end ## # Adds documentation for all methods in +klass+ to +out+ def add_method_documentation out, klass klass.method_list.each do |method| begin add_method out, method.full_name rescue NotFoundError next end end end ## # Adds a list of +methods+ to +out+ with a heading of +name+ def add_method_list out, methods, name return if methods.empty? out << RDoc::Markup::Heading.new(1, "#{name}:") out << RDoc::Markup::BlankLine.new if @use_stdout and !@interactive then out.concat methods.map { |method| RDoc::Markup::Verbatim.new method } else out << RDoc::Markup::IndentedParagraph.new(2, methods.join(', ')) end out << RDoc::Markup::BlankLine.new end ## # Returns ancestor classes of +klass+ def ancestors_of klass ancestors = [] unexamined = [klass] seen = [] loop do break if unexamined.empty? current = unexamined.shift seen << current stores = classes[current] next unless stores and not stores.empty? klasses = stores.flat_map do |store| store.ancestors[current] || [] end.uniq klasses = klasses - seen ancestors.concat klasses unexamined.concat klasses end ancestors.reverse end ## # For RubyGems backwards compatibility def class_cache # :nodoc: end ## # Builds a RDoc::Markup::Document from +found+, +klasess+ and +includes+ def class_document name, found, klasses, includes, extends also_in = [] out = RDoc::Markup::Document.new add_class out, name, klasses add_includes out, includes add_extends out, extends found.each do |store, klass| render_class out, store, klass, also_in end add_also_in out, also_in out end ## # Adds the class +comment+ to +out+. def class_document_comment out, comment # :nodoc: unless comment.empty? then out << RDoc::Markup::Rule.new(1) if comment.merged? then parts = comment.parts parts = parts.zip [RDoc::Markup::BlankLine.new] * parts.length parts.flatten! parts.pop out.concat parts else out << comment end end end ## # Adds the constants from +klass+ to the Document +out+. def class_document_constants out, klass # :nodoc: return if klass.constants.empty? out << RDoc::Markup::Heading.new(1, "Constants:") out << RDoc::Markup::BlankLine.new list = RDoc::Markup::List.new :NOTE constants = klass.constants.sort_by { |constant| constant.name } list.items.concat constants.map { |constant| parts = constant.comment.parts if constant.comment parts << RDoc::Markup::Paragraph.new('[not documented]') if parts.empty? RDoc::Markup::ListItem.new(constant.name, *parts) } out << list out << RDoc::Markup::BlankLine.new end ## # Hash mapping a known class or module to the stores it can be loaded from def classes return @classes if @classes @classes = {} @stores.each do |store| store.cache[:modules].each do |mod| # using default block causes searched-for modules to be added @classes[mod] ||= [] @classes[mod] << store end end @classes end ## # Returns the stores wherein +name+ is found along with the classes, # extends and includes that match it def classes_and_includes_and_extends_for name klasses = [] extends = [] includes = [] found = @stores.map do |store| begin klass = store.load_class name klasses << klass extends << [klass.extends, store] if klass.extends includes << [klass.includes, store] if klass.includes [store, klass] rescue RDoc::Store::MissingFileError end end.compact extends.reject! do |modules,| modules.empty? end includes.reject! do |modules,| modules.empty? end [found, klasses, includes, extends] end ## # Completes +name+ based on the caches. For Readline def complete name completions = [] klass, selector, method = parse_name name complete_klass name, klass, selector, method, completions complete_method name, klass, selector, completions completions.sort.uniq end def complete_klass name, klass, selector, method, completions # :nodoc: klasses = classes.keys # may need to include Foo when given Foo:: klass_name = method ? name : klass if name !~ /#|\./ then completions.replace klasses.grep(/^#{Regexp.escape klass_name}[^:]*$/) completions.concat klasses.grep(/^#{Regexp.escape name}[^:]*$/) if name =~ /::$/ completions << klass if classes.key? klass # to complete a method name elsif selector then completions << klass if classes.key? klass elsif classes.key? klass_name then completions << klass_name end end def complete_method name, klass, selector, completions # :nodoc: if completions.include? klass and name =~ /#|\.|::/ then methods = list_methods_matching name if not methods.empty? then # remove Foo if given Foo:: and a method was found completions.delete klass elsif selector then # replace Foo with Foo:: as given completions.delete klass completions << "#{klass}#{selector}" end completions.concat methods end end ## # Converts +document+ to text and writes it to the pager def display document page do |io| f = formatter(io) f.width = @width if @width and f.respond_to?(:width) text = document.accept f io.write text end end ## # Outputs formatted RI data for class +name+. Groups undocumented classes def display_class name return if name =~ /#|\./ found, klasses, includes, extends = classes_and_includes_and_extends_for name return if found.empty? out = class_document name, found, klasses, includes, extends display out end ## # Outputs formatted RI data for method +name+ def display_method name out = RDoc::Markup::Document.new add_method out, name display out end ## # Outputs formatted RI data for the class or method +name+. # # Returns true if +name+ was found, false if it was not an alternative could # be guessed, raises an error if +name+ couldn't be guessed. def display_name name if name =~ /\w:(\w|$)/ then display_page name return true end return true if display_class name display_method name if name =~ /::|#|\./ true rescue NotFoundError matches = list_methods_matching name if name =~ /::|#|\./ matches = classes.keys.grep(/^#{Regexp.escape name}/) if matches.empty? raise if matches.empty? page do |io| io.puts "#{name} not found, maybe you meant:" io.puts io.puts matches.sort.join("\n") end false end ## # Displays each name in +name+ def display_names names names.each do |name| name = expand_name name display_name name end end ## # Outputs formatted RI data for page +name+. def display_page name store_name, page_name = name.split ':', 2 store = @stores.find { |s| s.source == store_name } return display_page_list store if page_name.empty? pages = store.cache[:pages] unless pages.include? page_name then found_names = pages.select do |n| n =~ /#{Regexp.escape page_name}\.[^.]+$/ end if found_names.length.zero? then return display_page_list store, pages elsif found_names.length > 1 then return display_page_list store, found_names, page_name end page_name = found_names.first end page = store.load_page page_name display page.comment end ## # Outputs a formatted RI page list for the pages in +store+. def display_page_list store, pages = store.cache[:pages], search = nil out = RDoc::Markup::Document.new title = if search then "#{search} pages" else 'Pages' end out << RDoc::Markup::Heading.new(1, "#{title} in #{store.friendly_path}") out << RDoc::Markup::BlankLine.new list = RDoc::Markup::List.new(:BULLET) pages.each do |page| list << RDoc::Markup::Paragraph.new(page) end out << list display out end def check_did_you_mean # :nodoc: if defined? DidYouMean::SpellChecker true else begin require 'did_you_mean' if defined? DidYouMean::SpellChecker true else false end rescue LoadError false end end end ## # Expands abbreviated klass +klass+ into a fully-qualified class. "Zl::Da" # will be expanded to Zlib::DataError. def expand_class klass class_names = classes.keys ary = class_names.grep(Regexp.new("\\A#{klass.gsub(/(?=::|\z)/, '[^:]*')}\\z")) if ary.length != 1 && ary.first != klass if check_did_you_mean suggestions = DidYouMean::SpellChecker.new(dictionary: class_names).correct(klass) raise NotFoundError.new(klass, suggestions) else raise NotFoundError, klass end end ary.first end ## # Expands the class portion of +name+ into a fully-qualified class. See # #expand_class. def expand_name name klass, selector, method = parse_name name return [selector, method].join if klass.empty? case selector when ':' then [find_store(klass), selector, method] else [expand_class(klass), selector, method] end.join end ## # Filters the methods in +found+ trying to find a match for +name+. def filter_methods found, name regexp = name_regexp name filtered = found.find_all do |store, methods| methods.any? { |method| method.full_name =~ regexp } end return filtered unless filtered.empty? found end ## # Yields items matching +name+ including the store they were found in, the # class being searched for, the class they were found in (an ancestor) the # types of methods to look up (from #method_type), and the method name being # searched for def find_methods name klass, selector, method = parse_name name types = method_type selector klasses = nil ambiguous = klass.empty? if ambiguous then klasses = classes.keys else klasses = ancestors_of klass klasses.unshift klass end methods = [] klasses.each do |ancestor| ancestors = classes[ancestor] next unless ancestors klass = ancestor if ambiguous ancestors.each do |store| methods << [store, klass, ancestor, types, method] end end methods = methods.sort_by do |_, k, a, _, m| [k, a, m].compact end methods.each do |item| yield(*item) # :yields: store, klass, ancestor, types, method end self end ## # Finds a store that matches +name+ which can be the name of a gem, "ruby", # "home" or "site". # # See also RDoc::Store#source def find_store name @stores.each do |store| source = store.source return source if source == name return source if store.type == :gem and source =~ /^#{Regexp.escape name}-\d/ end raise RDoc::RI::Driver::NotFoundError, name end ## # Creates a new RDoc::Markup::Formatter. If a formatter is given with -f, # use it. If we're outputting to a pager, use bs, otherwise ansi. def formatter(io) if @formatter_klass then @formatter_klass.new elsif paging? or !io.tty? then RDoc::Markup::ToBs.new else RDoc::Markup::ToAnsi.new end end ## # Runs ri interactively using Readline if it is available. def interactive puts "\nEnter the method name you want to look up." begin require 'readline' rescue LoadError end if defined? Readline then Readline.completion_proc = method :complete puts "You can use tab to autocomplete." end puts "Enter a blank line to exit.\n\n" loop do name = if defined? Readline then Readline.readline ">> " else print ">> " $stdin.gets end return if name.nil? or name.empty? begin display_name expand_name(name.strip) rescue NotFoundError => e puts e.message end end rescue Interrupt exit end ## # Lists classes known to ri starting with +names+. If +names+ is empty all # known classes are shown. def list_known_classes names = [] classes = [] stores.each do |store| classes << store.module_names end classes = classes.flatten.uniq.sort unless names.empty? then filter = Regexp.union names.map { |name| /^#{name}/ } classes = classes.grep filter end page do |io| if paging? or io.tty? then if names.empty? then io.puts "Classes and Modules known to ri:" else io.puts "Classes and Modules starting with #{names.join ', '}:" end io.puts end io.puts classes.join("\n") end end ## # Returns an Array of methods matching +name+ def list_methods_matching name found = [] find_methods name do |store, klass, ancestor, types, method| if types == :instance or types == :both then methods = store.instance_methods[ancestor] if methods then matches = methods.grep(/^#{Regexp.escape method.to_s}/) matches = matches.map do |match| "#{klass}##{match}" end found.concat matches end end if types == :class or types == :both then methods = store.class_methods[ancestor] next unless methods matches = methods.grep(/^#{Regexp.escape method.to_s}/) matches = matches.map do |match| "#{klass}::#{match}" end found.concat matches end end found.uniq end ## # Loads RI data for method +name+ on +klass+ from +store+. +type+ and # +cache+ indicate if it is a class or instance method. def load_method store, cache, klass, type, name methods = store.public_send(cache)[klass] return unless methods method = methods.find do |method_name| method_name == name end return unless method store.load_method klass, "#{type}#{method}" rescue RDoc::Store::MissingFileError => e comment = RDoc::Comment.new("missing documentation at #{e.file}").parse method = RDoc::AnyMethod.new nil, name method.comment = comment method end ## # Returns an Array of RI data for methods matching +name+ def load_methods_matching name found = [] find_methods name do |store, klass, ancestor, types, method| methods = [] methods << load_method(store, :class_methods, ancestor, '::', method) if [:class, :both].include? types methods << load_method(store, :instance_methods, ancestor, '#', method) if [:instance, :both].include? types found << [store, methods.compact] end found.reject do |path, methods| methods.empty? end end ## # Returns a filtered list of methods matching +name+ def lookup_method name found = load_methods_matching name if found.empty? if check_did_you_mean methods = [] _, _, method_name = parse_name name find_methods name do |store, klass, ancestor, types, method| methods.push(*store.class_methods[klass]) if [:class, :both].include? types methods.push(*store.instance_methods[klass]) if [:instance, :both].include? types end methods = methods.uniq suggestions = DidYouMean::SpellChecker.new(dictionary: methods).correct(method_name) raise NotFoundError.new(name, suggestions) else raise NotFoundError, name end end filter_methods found, name end ## # Builds a RDoc::Markup::Document from +found+, +klasses+ and +includes+ def method_document name, filtered out = RDoc::Markup::Document.new out << RDoc::Markup::Heading.new(1, name) out << RDoc::Markup::BlankLine.new filtered.each do |store, methods| methods.each do |method| render_method out, store, method, name end end out end ## # Returns the type of method (:both, :instance, :class) for +selector+ def method_type selector case selector when '.', nil then :both when '#' then :instance else :class end end ## # Returns a regular expression for +name+ that will match an # RDoc::AnyMethod's name. def name_regexp name klass, type, name = parse_name name case type when '#', '::' then /^#{klass}#{type}#{Regexp.escape name}$/ else /^#{klass}(#|::)#{Regexp.escape name}$/ end end ## # Paginates output through a pager program. def page if pager = setup_pager then begin yield pager ensure pager.close end else yield $stdout end rescue Errno::EPIPE ensure @paging = false end ## # Are we using a pager? def paging? @paging end ## # Extracts the class, selector and method name parts from +name+ like # Foo::Bar#baz. # # NOTE: Given Foo::Bar, Bar is considered a class even though it may be a # method def parse_name name parts = name.split(/(::?|#|\.)/) if parts.length == 1 then if parts.first =~ /^[a-z]|^([%&*+\/<>^`|~-]|\+@|-@|<<|<=>?|===?|=>|=~|>>|\[\]=?|~@)$/ then type = '.' meth = parts.pop else type = nil meth = nil end elsif parts.length == 2 or parts.last =~ /::|#|\./ then type = parts.pop meth = nil elsif parts[1] == ':' then klass = parts.shift type = parts.shift meth = parts.join elsif parts[-2] != '::' or parts.last !~ /^[A-Z]/ then meth = parts.pop type = parts.pop end klass ||= parts.join [klass, type, meth] end ## # Renders the +klass+ from +store+ to +out+. If the klass has no # documentable items the class is added to +also_in+ instead. def render_class out, store, klass, also_in # :nodoc: comment = klass.comment # TODO the store's cache should always return an empty Array class_methods = store.class_methods[klass.full_name] || [] instance_methods = store.instance_methods[klass.full_name] || [] attributes = store.attributes[klass.full_name] || [] if comment.empty? and instance_methods.empty? and class_methods.empty? then also_in << store return end add_from out, store class_document_comment out, comment if class_methods or instance_methods or not klass.constants.empty? then out << RDoc::Markup::Rule.new(1) end class_document_constants out, klass add_method_list out, class_methods, 'Class methods' add_method_list out, instance_methods, 'Instance methods' add_method_list out, attributes, 'Attributes' add_method_documentation out, klass if @show_all end def render_method out, store, method, name # :nodoc: out << RDoc::Markup::Paragraph.new("(from #{store.friendly_path})") unless name =~ /^#{Regexp.escape method.parent_name}/ then out << RDoc::Markup::Heading.new(3, "Implementation from #{method.parent_name}") end out << RDoc::Markup::Rule.new(1) render_method_arguments out, method.arglists render_method_superclass out, method if method.is_alias_for al = method.is_alias_for alias_for = store.load_method al.parent_name, "#{al.name_prefix}#{al.name}" render_method_comment out, method, alias_for else render_method_comment out, method end end def render_method_arguments out, arglists # :nodoc: return unless arglists arglists = arglists.chomp.split "\n" arglists = arglists.map { |line| line + "\n" } out << RDoc::Markup::Verbatim.new(*arglists) out << RDoc::Markup::Rule.new(1) end def render_method_comment out, method, alias_for = nil# :nodoc: if alias_for unless method.comment.nil? or method.comment.empty? out << RDoc::Markup::BlankLine.new out << method.comment end out << RDoc::Markup::BlankLine.new out << RDoc::Markup::Paragraph.new("(This method is an alias for #{alias_for.full_name}.)") out << RDoc::Markup::BlankLine.new out << alias_for.comment out << RDoc::Markup::BlankLine.new else out << RDoc::Markup::BlankLine.new out << method.comment out << RDoc::Markup::BlankLine.new end end def render_method_superclass out, method # :nodoc: return unless method.respond_to?(:superclass_method) and method.superclass_method out << RDoc::Markup::BlankLine.new out << RDoc::Markup::Heading.new(4, "(Uses superclass method #{method.superclass_method})") out << RDoc::Markup::Rule.new(1) end ## # Looks up and displays ri data according to the options given. def run if @list_doc_dirs then puts @doc_dirs elsif @list then list_known_classes @names elsif @server then start_server elsif @interactive or @names.empty? then interactive else display_names @names end rescue NotFoundError => e abort e.message end ## # Sets up a pager program to pass output through. Tries the RI_PAGER and # PAGER environment variables followed by pager, less then more. def setup_pager return if @use_stdout pagers = [ENV['RI_PAGER'], ENV['PAGER'], 'pager', 'less', 'more'] require 'shellwords' pagers.compact.uniq.each do |pager| pager = Shellwords.split(pager) next if pager.empty? io = IO.popen(pager, 'w') rescue next next if $? and $?.pid == io.pid and $?.exited? # pager didn't work @paging = true return io end @use_stdout = true nil end ## # Starts a WEBrick server for ri. def start_server begin require 'webrick' rescue LoadError abort "webrick is not found. You may need to `gem install webrick` to install webrick." end server = WEBrick::HTTPServer.new :Port => @server extra_doc_dirs = @stores.map {|s| s.type == :extra ? s.path : nil}.compact server.mount '/', RDoc::Servlet, nil, extra_doc_dirs trap 'INT' do server.shutdown end trap 'TERM' do server.shutdown end server.start end end PK!x8W parser.rbnu[# -*- coding: us-ascii -*- # frozen_string_literal: true ## # A parser is simple a class that subclasses RDoc::Parser and implements #scan # to fill in an RDoc::TopLevel with parsed data. # # The initialize method takes an RDoc::TopLevel to fill with parsed content, # the name of the file to be parsed, the content of the file, an RDoc::Options # object and an RDoc::Stats object to inform the user of parsed items. The # scan method is then called to parse the file and must return the # RDoc::TopLevel object. By calling super these items will be set for you. # # In order to be used by RDoc the parser needs to register the file extensions # it can parse. Use ::parse_files_matching to register extensions. # # require 'rdoc' # # class RDoc::Parser::Xyz < RDoc::Parser # parse_files_matching /\.xyz$/ # # def initialize top_level, file_name, content, options, stats # super # # # extra initialization if needed # end # # def scan # # parse file and fill in @top_level # end # end class RDoc::Parser @parsers = [] class << self ## # An Array of arrays that maps file extension (or name) regular # expressions to parser classes that will parse matching filenames. # # Use parse_files_matching to register a parser's file extensions. attr_reader :parsers end ## # The name of the file being parsed attr_reader :file_name ## # Alias an extension to another extension. After this call, files ending # "new_ext" will be parsed using the same parser as "old_ext" def self.alias_extension(old_ext, new_ext) old_ext = old_ext.sub(/^\.(.*)/, '\1') new_ext = new_ext.sub(/^\.(.*)/, '\1') parser = can_parse_by_name "xxx.#{old_ext}" return false unless parser RDoc::Parser.parsers.unshift [/\.#{new_ext}$/, parser] true end ## # Determines if the file is a "binary" file which basically means it has # content that an RDoc parser shouldn't try to consume. def self.binary?(file) return false if file =~ /\.(rdoc|txt)$/ s = File.read(file, 1024) or return false return true if s[0, 2] == Marshal.dump('')[0, 2] or s.index("\x00") mode = 'r:utf-8' # default source encoding has been changed to utf-8 s.sub!(/\A#!.*\n/, '') # assume shebang line isn't longer than 1024. encoding = s[/^\s*\#\s*(?:-\*-\s*)?(?:en)?coding:\s*([^\s;]+?)(?:-\*-|[\s;])/, 1] mode = "rb:#{encoding}" if encoding s = File.open(file, mode) {|f| f.gets(nil, 1024)} not s.valid_encoding? end ## # Checks if +file+ is a zip file in disguise. Signatures from # http://www.garykessler.net/library/file_sigs.html def self.zip? file zip_signature = File.read file, 4 zip_signature == "PK\x03\x04" or zip_signature == "PK\x05\x06" or zip_signature == "PK\x07\x08" rescue false end ## # Return a parser that can handle a particular extension def self.can_parse file_name parser = can_parse_by_name file_name # HACK Selenium hides a jar file using a .txt extension return if parser == RDoc::Parser::Simple and zip? file_name parser end ## # Returns a parser that can handle the extension for +file_name+. This does # not depend upon the file being readable. def self.can_parse_by_name file_name _, parser = RDoc::Parser.parsers.find { |regexp,| regexp =~ file_name } # The default parser must not parse binary files ext_name = File.extname file_name return parser if ext_name.empty? if parser == RDoc::Parser::Simple and ext_name !~ /txt|rdoc/ then case check_modeline file_name when nil, 'rdoc' then # continue else return nil end end parser rescue Errno::EACCES end ## # Returns the file type from the modeline in +file_name+ def self.check_modeline file_name line = File.open file_name do |io| io.gets end /-\*-\s*(.*?\S)\s*-\*-/ =~ line return nil unless type = $1 if /;/ =~ type then return nil unless /(?:\s|\A)mode:\s*([^\s;]+)/i =~ type type = $1 end return nil if /coding:/i =~ type type.downcase rescue ArgumentError rescue Encoding::InvalidByteSequenceError # invalid byte sequence end ## # Finds and instantiates the correct parser for the given +file_name+ and # +content+. def self.for top_level, file_name, content, options, stats return if binary? file_name parser = use_markup content unless parser then parse_name = file_name # If no extension, look for shebang if file_name !~ /\.\w+$/ && content =~ %r{\A#!(.+)} then shebang = $1 case shebang when %r{env\s+ruby}, %r{/ruby} parse_name = 'dummy.rb' end end parser = can_parse parse_name end return unless parser content = remove_modeline content parser.new top_level, file_name, content, options, stats rescue SystemCallError nil end ## # Record which file types this parser can understand. # # It is ok to call this multiple times. def self.parse_files_matching(regexp) RDoc::Parser.parsers.unshift [regexp, self] end ## # Removes an emacs-style modeline from the first line of the document def self.remove_modeline content content.sub(/\A.*-\*-\s*(.*?\S)\s*-\*-.*\r?\n/, '') end ## # If there is a markup: parser_name comment at the front of the # file, use it to determine the parser. For example: # # # markup: rdoc # # Class comment can go here # # class C # end # # The comment should appear as the first line of the +content+. # # If the content contains a shebang or editor modeline the comment may # appear on the second or third line. # # Any comment style may be used to hide the markup comment. def self.use_markup content markup = content.lines.first(3).grep(/markup:\s+(\w+)/) { $1 }.first return unless markup # TODO Ruby should be returned only when the filename is correct return RDoc::Parser::Ruby if %w[tomdoc markdown].include? markup markup = Regexp.escape markup _, selected = RDoc::Parser.parsers.find do |_, parser| /^#{markup}$/i =~ parser.name.sub(/.*:/, '') end selected end ## # Creates a new Parser storing +top_level+, +file_name+, +content+, # +options+ and +stats+ in instance variables. In +@preprocess+ an # RDoc::Markup::PreProcess object is created which allows processing of # directives. def initialize top_level, file_name, content, options, stats @top_level = top_level @top_level.parser = self.class @store = @top_level.store @file_name = file_name @content = content @options = options @stats = stats @preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include @preprocess.options = @options end autoload :RubyTools, "#{__dir__}/parser/ruby_tools" autoload :Text, "#{__dir__}/parser/text" ## # Normalizes tabs in +body+ def handle_tab_width(body) if /\t/ =~ body tab_width = @options.tab_width body.split(/\n/).map do |line| 1 while line.gsub!(/\t+/) do b, e = $~.offset(0) ' ' * (tab_width * (e-b) - b % tab_width) end line end.join "\n" else body end end end # simple must come first in order to show up last in the parsers list require_relative 'parser/simple' require_relative 'parser/c' require_relative 'parser/changelog' require_relative 'parser/markdown' require_relative 'parser/rd' require_relative 'parser/ruby' PK!~'@@WEBrick/HTTPResponse.htmlnu[ Class: WEBrick::HTTPResponse

    Files

    Class/Module Index [+]

    Quicksearch

    WEBrick::HTTPResponse

    This monkey patch allows for applications to perform their own chunking through WEBrick::HTTPResponse iff rack is set to true.

    Attributes

    rack[RW]

    Public Instance Methods

    _rack_setup_header() click to toggle source
    Alias for: setup_header
    setup_header() click to toggle source
    # File lib/rack/handler/webrick.rb, line 11
    def setup_header
      app_chunking = rack && @header['transfer-encoding'] == 'chunked'
    
      @chunked = app_chunking if app_chunking
    
      _rack_setup_header
    
      @chunked = false if app_chunking
    end
    Also aliased as: _rack_setup_header

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!E4B#0#0 FCGI.htmlnu[ Module: FCGI

    In Files

    Namespace

    Files

    Class/Module Index [+]

    Quicksearch

    FCGI

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK! 11 index.htmlnu[ rack-1.6.4 Documentation

    rack-1.6.4 Documentation

    This is the API documentation for 'rack-1.6.4 Documentation'.

    Files

    Classes/Modules

    Methods

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!K<<FCGI/Stream.htmlnu[ Class: FCGI::Stream

    Files

    Class/Module Index [+]

    Quicksearch

    FCGI::Stream

    Public Instance Methods

    _rack_read_without_buffer(n, buffer=nil) click to toggle source
    Alias for: read
    read(n, buffer=nil) click to toggle source
    # File lib/rack/handler/fastcgi.rb, line 10
    def read(n, buffer=nil)
      buf = _rack_read_without_buffer n
      buffer.replace(buf.to_s)  if buffer
      buf
    end
    Also aliased as: _rack_read_without_buffer

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!+L;0;0 WEBrick.htmlnu[ Module: WEBrick

    In Files

    Namespace

    Files

    Class/Module Index [+]

    Quicksearch

    WEBrick

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!}5}5rdoc.cssnu[/* * "Darkfish" Rdoc CSS * $Id: rdoc.css 54 2009-01-27 01:09:48Z deveiant $ * * Author: Michael Granger * */ /* Base Green is: #6C8C22 */ *{ padding: 0; margin: 0; } body { background: #efefef; font: 14px "Helvetica Neue", Helvetica, Tahoma, sans-serif; } body.class, body.module, body.file { margin-left: 40px; } body.file-popup { font-size: 90%; margin-left: 0; } h1 { font-size: 300%; text-shadow: rgba(135,145,135,0.65) 2px 2px 3px; color: #6C8C22; } h2,h3,h4 { margin-top: 1.5em; } :link, :visited { color: #6C8C22; text-decoration: none; } :link:hover, :visited:hover { border-bottom: 1px dotted #6C8C22; } pre { background: #ddd; padding: 0.5em 0; } /* @group Generic Classes */ .initially-hidden { display: none; } .quicksearch-field { width: 98%; background: #ddd; border: 1px solid #aaa; height: 1.5em; -webkit-border-radius: 4px; } .quicksearch-field:focus { background: #f1edba; } .missing-docs { font-size: 120%; background: white url(images/wrench_orange.png) no-repeat 4px center; color: #ccc; line-height: 2em; border: 1px solid #d00; opacity: 1; padding-left: 20px; text-indent: 24px; letter-spacing: 3px; font-weight: bold; -webkit-border-radius: 5px; -moz-border-radius: 5px; } .target-section { border: 2px solid #dcce90; border-left-width: 8px; padding: 0 1em; background: #fff3c2; } /* @end */ /* @group Index Page, Standalone file pages */ body.indexpage { margin: 1em 3em; } body.indexpage p, body.indexpage div, body.file p { margin: 1em 0; } .indexpage .rdoc-list p, .file .rdoc-list p { margin: 0em 0; } .indexpage ol, .file #documentation ol { line-height: 160%; } .indexpage ul, .file #documentation ul { line-height: 160%; list-style: none; } .indexpage ul :link, .indexpage ul :visited { font-size: 16px; } .indexpage li, .file #documentation li { padding-left: 20px; } .indexpage ol, .file #documentation ol { margin-left: 20px; } .indexpage ol > li, .file #documentation ol > li { padding-left: 0; } .indexpage ul > li, .file #documentation ul > li { background: url(images/bullet_black.png) no-repeat left 4px; } .indexpage li.module { background: url(images/package.png) no-repeat left 4px; } .indexpage li.class { background: url(images/ruby.png) no-repeat left 4px; } .indexpage li.file { background: url(images/page_white_text.png) no-repeat left 4px; } .file li p, .indexpage li p { margin: 0 0; } /* @end */ /* @group Top-Level Structure */ .class #metadata, .file #metadata, .module #metadata { float: left; width: 260px; } .class #documentation, .file #documentation, .module #documentation { margin: 2em 1em 5em 300px; min-width: 340px; } .file #metadata { margin: 0.8em; } #validator-badges { clear: both; margin: 1em 1em 2em; } /* @end */ /* @group Metadata Section */ #metadata .section { background-color: #dedede; -moz-border-radius: 5px; -webkit-border-radius: 5px; border: 1px solid #aaa; margin: 0 8px 16px; font-size: 90%; overflow: hidden; } #metadata h3.section-header { margin: 0; padding: 2px 8px; background: #ccc; color: #666; -moz-border-radius-topleft: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-left-radius: 4px; -webkit-border-top-right-radius: 4px; border-bottom: 1px solid #aaa; } #metadata #home-section h3.section-header { border-bottom: 0; } #metadata ul, #metadata dl, #metadata p { padding: 8px; list-style: none; } #file-metadata ul { padding-left: 28px; list-style-image: url(images/page_green.png); } dl.svninfo { color: #666; margin: 0; } dl.svninfo dt { font-weight: bold; } ul.link-list li { white-space: nowrap; } ul.link-list .type { font-size: 8px; text-transform: uppercase; color: white; background: #969696; padding: 2px 4px; -webkit-border-radius: 5px; } /* @end */ /* @group Project Metadata Section */ #project-metadata { margin-top: 3em; } .file #project-metadata { margin-top: 0em; } #project-metadata .section { border: 1px solid #aaa; } #project-metadata h3.section-header { border-bottom: 1px solid #aaa; position: relative; } #project-metadata h3.section-header .search-toggle { position: absolute; right: 5px; } #project-metadata form { color: #777; background: #ccc; padding: 8px 8px 16px; border-bottom: 1px solid #bbb; } #project-metadata fieldset { border: 0; } #no-class-search-results { margin: 0 auto 1em; text-align: center; font-size: 14px; font-weight: bold; color: #aaa; } /* @end */ /* @group Documentation Section */ .description { font-size: 100%; color: #333; } .description p { margin: 1em 0.4em; } .description li p { margin: 0; } .description ul { margin-left: 1.5em; } .description ul li { line-height: 1.4em; } .description dl, #documentation dl { margin: 8px 1.5em; border: 1px solid #ccc; } .description dl { font-size: 14px; } .description dt, #documentation dt { padding: 2px 4px; font-weight: bold; background: #ddd; } .description dd, #documentation dd { padding: 2px 12px; } .description dd + dt, #documentation dd + dt { margin-top: 0.7em; } #documentation .section { font-size: 90%; } #documentation h2.section-header { margin-top: 2em; padding: 0.75em 0.5em; background: #ccc; color: #333; font-size: 175%; border: 1px solid #bbb; -moz-border-radius: 3px; -webkit-border-radius: 3px; } #documentation h3.section-header { margin-top: 2em; padding: 0.25em 0.5em; background-color: #dedede; color: #333; font-size: 150%; border: 1px solid #bbb; -moz-border-radius: 3px; -webkit-border-radius: 3px; } #constants-list > dl, #attributes-list > dl { margin: 1em 0 2em; border: 0; } #constants-list > dl dt, #attributes-list > dl dt { padding-left: 0; font-weight: bold; font-family: Monaco, "Andale Mono"; background: inherit; } #constants-list > dl dt a, #attributes-list > dl dt a { color: inherit; } #constants-list > dl dd, #attributes-list > dl dd { margin: 0 0 1em 0; padding: 0; color: #666; } .documentation-section h2 { position: relative; } .documentation-section h2 a { position: absolute; top: 8px; right: 10px; font-size: 12px; color: #9b9877; visibility: hidden; } .documentation-section h2:hover a { visibility: visible; } /* @group Method Details */ #documentation .method-source-code { display: none; } #documentation .method-detail { margin: 0.5em 0; padding: 0.5em 0; cursor: pointer; } #documentation .method-detail:hover { background-color: #f1edba; } #documentation .method-heading { position: relative; padding: 2px 4px 0 20px; font-size: 125%; font-weight: bold; color: #333; background: url(images/brick.png) no-repeat left bottom; } #documentation .method-heading :link, #documentation .method-heading :visited { color: inherit; } #documentation .method-click-advice { position: absolute; top: 2px; right: 5px; font-size: 10px; color: #9b9877; visibility: hidden; padding-right: 20px; line-height: 20px; background: url(images/zoom.png) no-repeat right top; } #documentation .method-detail:hover .method-click-advice { visibility: visible; } #documentation .method-alias .method-heading { color: #666; background: url(images/brick_link.png) no-repeat left bottom; } #documentation .method-description, #documentation .aliases { margin: 0 20px; color: #666; } #documentation .method-description p, #documentation .aliases p { line-height: 1.2em; } #documentation .aliases { padding-top: 4px; font-style: italic; cursor: default; } #documentation .method-description p { padding: 0; } #documentation .method-description p + p { margin-bottom: 0.5em; } #documentation .method-description ul { margin-left: 1.5em; } #documentation .attribute-method-heading { background: url(images/tag_green.png) no-repeat left bottom; } #documentation #attribute-method-details .method-detail:hover { background-color: transparent; cursor: default; } #documentation .attribute-access-type { font-size: 60%; text-transform: uppercase; vertical-align: super; padding: 0 2px; } /* @end */ /* @end */ /* @group Source Code */ div.method-source-code { background: #262626; color: #efefef; margin: 1em; padding: 0.5em; border: 1px dashed #999; overflow: hidden; } div.method-source-code pre { background: inherit; padding: 0; color: white; overflow: auto; } /* @group Ruby keyword styles */ .ruby-constant { color: #7fffd4; background: transparent; } .ruby-keyword { color: #00ffff; background: transparent; } .ruby-ivar { color: #eedd82; background: transparent; } .ruby-operator { color: #00ffee; background: transparent; } .ruby-identifier { color: #ffdead; background: transparent; } .ruby-node { color: #ffa07a; background: transparent; } .ruby-comment { color: #b22222; font-weight: bold; background: transparent; } .ruby-regexp { color: #ffa07a; background: transparent; } .ruby-value { color: #7fffd4; background: transparent; } /* @end */ /* @end */ /* @group File Popup Contents */ .file #metadata, .file-popup #metadata { } .file-popup dl { font-size: 80%; padding: 0.75em; background-color: #dedede; color: #333; border: 1px solid #bbb; -moz-border-radius: 3px; -webkit-border-radius: 3px; } .file dt { font-weight: bold; padding-left: 22px; line-height: 20px; background: url(images/page_white_width.png) no-repeat left top; } .file dt.modified-date { background: url(images/date.png) no-repeat left top; } .file dt.requires { background: url(images/plugin.png) no-repeat left top; } .file dt.scs-url { background: url(images/wrench.png) no-repeat left top; } .file dl dd { margin: 0 0 1em 0; } .file #metadata dl dd ul { list-style: circle; margin-left: 20px; padding-top: 0; } .file #metadata dl dd ul li { } .file h2 { margin-top: 2em; padding: 0.75em 0.5em; background-color: #dedede; color: #333; font-size: 120%; border: 1px solid #bbb; -moz-border-radius: 3px; -webkit-border-radius: 3px; } /* @end */ /* @group ThickBox Styles */ #TB_window { font: 12px Arial, Helvetica, sans-serif; color: #333333; } #TB_secondLine { font: 10px Arial, Helvetica, sans-serif; color:#666666; } #TB_window :link, #TB_window :visited { color: #666666; } #TB_window :link:hover, #TB_window :visited:hover { color: #000; } #TB_window :link:active, #TB_window :visited:active { color: #666666; } #TB_window :link:focus, #TB_window :visited:focus { color: #666666; } #TB_overlay { position: fixed; z-index:100; top: 0px; left: 0px; height:100%; width:100%; } .TB_overlayMacFFBGHack {background: url(images/macFFBgHack.png) repeat;} .TB_overlayBG { background-color:#000; filter:alpha(opacity=75); -moz-opacity: 0.75; opacity: 0.75; } * html #TB_overlay { /* ie6 hack */ position: absolute; height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); } #TB_window { position: fixed; background: #ffffff; z-index: 102; color:#000000; display:none; border: 4px solid #525252; text-align:left; top:50%; left:50%; } * html #TB_window { /* ie6 hack */ position: absolute; margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); } #TB_window img#TB_Image { display:block; margin: 15px 0 0 15px; border-right: 1px solid #ccc; border-bottom: 1px solid #ccc; border-top: 1px solid #666; border-left: 1px solid #666; } #TB_caption{ height:25px; padding:7px 30px 10px 25px; float:left; } #TB_closeWindow{ height:25px; padding:11px 25px 10px 0; float:right; } #TB_closeAjaxWindow{ padding:7px 10px 5px 0; margin-bottom:1px; text-align:right; float:right; } #TB_ajaxWindowTitle{ float:left; padding:7px 0 5px 10px; margin-bottom:1px; font-size: 22px; } #TB_title{ background-color: #6C8C22; color: #dedede; height:40px; } #TB_title :link, #TB_title :visited { color: white !important; border-bottom: 1px dotted #dedede; } #TB_ajaxContent{ clear:both; padding:2px 15px 15px 15px; overflow:auto; text-align:left; line-height:1.4em; } #TB_ajaxContent.TB_modal{ padding:15px; } #TB_ajaxContent p{ padding:5px 0px 5px 0px; } #TB_load{ position: fixed; display:none; height:13px; width:208px; z-index:103; top: 50%; left: 50%; margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */ } * html #TB_load { /* ie6 hack */ position: absolute; margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px'); } #TB_HideSelect{ z-index:99; position:fixed; top: 0; left: 0; background-color:#fff; border:none; filter:alpha(opacity=0); -moz-opacity: 0; opacity: 0; height:100%; width:100%; } * html #TB_HideSelect { /* ie6 hack */ position: absolute; height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px'); } #TB_iframeContent{ clear:both; border:none; margin-bottom:-1px; margin-top:1px; _margin-bottom:1px; } /* @end */ /* @group Debugging Section */ #debugging-toggle { text-align: center; } #debugging-toggle img { cursor: pointer; } #rdoc-debugging-section-dump { display: none; margin: 0 2em 2em; background: #ccc; border: 1px solid #999; } /* @end */ PK! |;ff js/jquery.jsnu[/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */ (function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"":"")+""),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bg(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i=0===c})}function U(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function M(a,b){return(a&&a!=="*"?a+".":"")+b.replace(y,"`").replace(z,"&")}function L(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;ic)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function J(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function D(){return!0}function C(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function K(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(K,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.4",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c
    a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-1000px",top:"-1000px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
    ",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
    t
    ",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i=f.expando,j=typeof c=="string",k=a.nodeType,l=k?f.cache:a,m=k?a[f.expando]:a[f.expando]&&f.expando;if((!m||e&&m&&l[m]&&!l[m][i])&&j&&d===b)return;m||(k?a[f.expando]=m=++f.uuid:m=f.expando),l[m]||(l[m]={},k||(l[m].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?l[m][i]=f.extend(l[m][i],c):l[m]=f.extend(l[m],c);g=l[m],e&&(g[i]||(g[i]={}),g=g[i]),d!==b&&(g[f.camelCase(c)]=d);if(c==="events"&&!g[c])return g[i]&&g[i].events;j?(h=g[c],h==null&&(h=g[f.camelCase(c)])):h=g;return h}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e=f.expando,g=a.nodeType,h=g?f.cache:a,i=g?a[f.expando]:f.expando;if(!h[i])return;if(b){d=c?h[i][e]:h[i];if(d){d[b]||(b=f.camelCase(b)),delete d[b];if(!l(d))return}}if(c){delete h[i][e];if(!l(h[i]))return}var j=h[i][e];f.support.deleteExpando||!h.setInterval?delete h[i]:h[i]=null,j?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=j):g&&(f.support.deleteExpando?delete a[f.expando]:a.removeAttribute?a.removeAttribute(f.expando):a[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=v:u&&(i=u)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.attr(a,b,""),a.removeAttribute(b),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(u&&f.nodeName(a,"button"))return u.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(u&&f.nodeName(a,"button"))return u.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==null?g:a[c]},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabIndex=f.propHooks.tabIndex,v={get:function(a,c){var d;return f.prop(a,c)===!0||(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(u=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var w=/\.(.*)$/,x=/^(?:textarea|input|select)$/i,y=/\./g,z=/ /g,A=/[^\w\s.|`]/g,B=function(a){return a.replace(A,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=C;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=C);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),B).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},I=function(c){var d=c.target,e,g;if(!!x.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=H(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:I,beforedeactivate:I,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&I.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&I.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",H(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in G)f.event.add(this,c+".specialChange",G[c]);return x.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return x.test(this.nodeName)}},G=f.event.special.change.filters,G.focus=G.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

    ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
    ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g0)for(h=g;h0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=S.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(U(c[0])||U(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=R.call(arguments);N.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!T[a]?f.unique(e):e,(this.length>1||P.test(d))&&O.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]};be.optgroup=be.option,be.tbody=be.tfoot=be.colgroup=be.caption=be.thead,be.th=be.td,f.support.htmlSerialize||(be._default=[1,"div
    ","
    "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!be[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)g[h]&&bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=be[l]||be._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bn.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bm,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bm.test(g)?g.replace(bm,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bv(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bw=function(a,c){var d,e,g;c=c.replace(bo,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bx=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bp.test(d)&&bq.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bv=bw||bx,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bz=/%20/g,bA=/\[\]$/,bB=/\r?\n/g,bC=/#.*$/,bD=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bE=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bF=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bG=/^(?:GET|HEAD)$/,bH=/^\/\//,bI=/\?/,bJ=/)<[^<]*)*<\/script>/gi,bK=/^(?:select|textarea)/i,bL=/\s+/,bM=/([?&])_=[^&]*/,bN=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bO=f.fn.load,bP={},bQ={},bR,bS,bT=["*/"]+["*"];try{bR=e.href}catch(bU){bR=c.createElement("a"),bR.href="",bR=bR.href}bS=bN.exec(bR.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bO)return bO.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
    ").append(c.replace(bJ,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bK.test(this.nodeName)||bE.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bB,"\r\n")}}):{name:b.name,value:c.replace(bB,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?bX(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),bX(a,b);return a},ajaxSettings:{url:bR,isLocal:bF.test(bS[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bT},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bV(bP),ajaxTransport:bV(bQ),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?bZ(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=b$(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bD.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bC,"").replace(bH,bS[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bL),d.crossDomain==null&&(r=bN.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bS[1]&&r[2]==bS[2]&&(r[3]||(r[1]==="http:"?80:443))==(bS[3]||(bS[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bW(bP,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bG.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bI.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bM,"$1_="+x);d.url=y+(y===d.url?(bI.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bT+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bW(bQ,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bz,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cq("show",3),a,b,c);for(var g=0,h=this.length;g=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b
    ";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=ct.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!ct.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cu(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cu(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNaN(j)?i:j}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window);PK!$ js/darkfish.jsnu[/** * * 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() {}; }; /** * Unwrap the first element that matches the given @expr@ from the targets and return them. */ $.fn.unwrap = function( expr ) { return this.each( function() { $(this).parents( expr ).eq( 0 ).after( this ).remove(); }); }; function showSource( e ) { var target = e.target; var codeSections = $(target). parents('.method-detail'). find('.method-source-code'); $(target). parents('.method-detail'). find('.method-source-code'). slideToggle(); }; function hookSourceViews() { $('.method-description,.method-heading').click( showSource ); }; function toggleDebuggingSection() { $('.debugging-section').slideToggle(); }; function hookDebuggingToggle() { $('#debugging-toggle img').click( toggleDebuggingSection ); }; function hookQuickSearch() { $('.quicksearch-field').each( function() { var searchElems = $(this).parents('.section').find( 'li' ); var toggle = $(this).parents('.section').find('h3 .search-toggle'); // console.debug( "Toggle is: %o", toggle ); var qsbox = $(this).parents('form').get( 0 ); $(this).quicksearch( this, searchElems, { noSearchResultsIndicator: 'no-class-search-results', focusOnLoad: false }); $(toggle).click( function() { // console.debug( "Toggling qsbox: %o", qsbox ); $(qsbox).toggle(); }); }); }; function highlightTarget( anchor ) { console.debug( "Highlighting target '%s'.", anchor ); $("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." ); } } }); }; function highlightLocationTarget() { console.debug( "Location hash: %s", window.location.hash ); if ( ! window.location.hash || window.location.hash.length == 0 ) return; var anchor = window.location.hash.substring(1); console.debug( "Found anchor: %s; matching %s", anchor, "a[name=" + anchor + "]" ); highlightTarget( anchor ); }; function highlightClickTarget( event ) { console.debug( "Highlighting click target for event %o", event.target ); try { var anchor = $(event.target).attr( 'href' ).substring(1); console.debug( "Found target anchor: %s", anchor ); highlightTarget( anchor ); } catch ( err ) { console.error( "Exception while highlighting: %o", err ); }; }; $(document).ready( function() { hookSourceViews(); hookDebuggingToggle(); hookQuickSearch(); highlightLocationTarget(); $('ul.link-list a').bind( "click", highlightClickTarget ); }); PK!/qZZjs/thickbox-compressed.jsnu[/* * Thickbox 3 - One Box To Rule Them All. * By Cody Lindley (http://www.codylindley.com) * Copyright (c) 2007 cody lindley * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php */ var tb_pathToImage = "../images/loadingAnimation.gif"; eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('$(o).2S(9(){1u(\'a.18, 3n.18, 3i.18\');1w=1p 1t();1w.L=2H});9 1u(b){$(b).s(9(){6 t=X.Q||X.1v||M;6 a=X.u||X.23;6 g=X.1N||P;19(t,a,g);X.2E();H P})}9 19(d,f,g){3m{3(2t o.v.J.2i==="2g"){$("v","11").r({A:"28%",z:"28%"});$("11").r("22","2Z");3(o.1Y("1F")===M){$("v").q("<4 5=\'B\'><4 5=\'8\'>");$("#B").s(G)}}n{3(o.1Y("B")===M){$("v").q("<4 5=\'B\'><4 5=\'8\'>");$("#B").s(G)}}3(1K()){$("#B").1J("2B")}n{$("#B").1J("2z")}3(d===M){d=""}$("v").q("<4 5=\'K\'><1I L=\'"+1w.L+"\' />");$(\'#K\').2y();6 h;3(f.O("?")!==-1){h=f.3l(0,f.O("?"))}n{h=f}6 i=/\\.2s$|\\.2q$|\\.2m$|\\.2l$|\\.2k$/;6 j=h.1C().2h(i);3(j==\'.2s\'||j==\'.2q\'||j==\'.2m\'||j==\'.2l\'||j==\'.2k\'){1D="";1G="";14="";1z="";1x="";R="";1n="";1r=P;3(g){E=$("a[@1N="+g+"]").36();25(D=0;((D&1d;&1d;2T &2R;"}n{1D=E[D].Q;1G=E[D].u;14="<1e 5=\'1U\'>&1d;&1d;&2O; 2N"}}n{1r=1b;1n="1t "+(D+1)+" 2L "+(E.1c)}}}S=1p 1t();S.1g=9(){S.1g=M;6 a=2x();6 x=a[0]-1M;6 y=a[1]-1M;6 b=S.z;6 c=S.A;3(b>x){c=c*(x/b);b=x;3(c>y){b=b*(y/c);c=y}}n 3(c>y){b=b*(y/c);c=y;3(b>x){c=c*(x/b);b=x}}13=b+30;1a=c+2G;$("#8").q("<1I 5=\'2F\' L=\'"+f+"\' z=\'"+b+"\' A=\'"+c+"\' 23=\'"+d+"\'/>"+"<4 5=\'2D\'>"+d+"<4 5=\'2C\'>"+1n+14+R+"<4 5=\'2A\'>1l 1k 1j 1s");$("#Z").s(G);3(!(14==="")){9 12(){3($(o).N("s",12)){$(o).N("s",12)}$("#8").C();$("v").q("<4 5=\'8\'>");19(1D,1G,g);H P}$("#1U").s(12)}3(!(R==="")){9 1i(){$("#8").C();$("v").q("<4 5=\'8\'>");19(1z,1x,g);H P}$("#1X").s(1i)}o.1h=9(e){3(e==M){I=2w.2v}n{I=e.2u}3(I==27){G()}n 3(I==3k){3(!(R=="")){o.1h="";1i()}}n 3(I==3j){3(!(14=="")){o.1h="";12()}}};16();$("#K").C();$("#1L").s(G);$("#8").r({Y:"T"})};S.L=f}n{6 l=f.2r(/^[^\\?]+\\??/,\'\');6 m=2p(l);13=(m[\'z\']*1)+30||3h;1a=(m[\'A\']*1)+3g||3f;W=13-30;V=1a-3e;3(f.O(\'2j\')!=-1){1E=f.1B(\'3d\');$("#15").C();3(m[\'1A\']!="1b"){$("#8").q("<4 5=\'2f\'><4 5=\'1H\'>"+d+"<4 5=\'2e\'>1l 1k 1j 1s ")}n{$("#B").N();$("#8").q(" ")}}n{3($("#8").r("Y")!="T"){3(m[\'1A\']!="1b"){$("#8").q("<4 5=\'2f\'><4 5=\'1H\'>"+d+"<4 5=\'2e\'>1l 1k 1j 1s<4 5=\'F\' J=\'z:"+W+"p;A:"+V+"p\'>")}n{$("#B").N();$("#8").q("<4 5=\'F\' 3c=\'3b\' J=\'z:"+W+"p;A:"+V+"p;\'>")}}n{$("#F")[0].J.z=W+"p";$("#F")[0].J.A=V+"p";$("#F")[0].3a=0;$("#1H").11(d)}}$("#Z").s(G);3(f.O(\'37\')!=-1){$("#F").q($(\'#\'+m[\'26\']).1T());$("#8").24(9(){$(\'#\'+m[\'26\']).q($("#F").1T())});16();$("#K").C();$("#8").r({Y:"T"})}n 3(f.O(\'2j\')!=-1){16();3($.1q.35){$("#K").C();$("#8").r({Y:"T"})}}n{$("#F").34(f+="&1y="+(1p 33().32()),9(){16();$("#K").C();1u("#F a.18");$("#8").r({Y:"T"})})}}3(!m[\'1A\']){o.21=9(e){3(e==M){I=2w.2v}n{I=e.2u}3(I==27){G()}}}}31(e){}}9 1m(){$("#K").C();$("#8").r({Y:"T"})}9 G(){$("#2Y").N("s");$("#Z").N("s");$("#8").2X("2W",9(){$(\'#8,#B,#1F\').2V("24").N().C()});$("#K").C();3(2t o.v.J.2i=="2g"){$("v","11").r({A:"1Z",z:"1Z"});$("11").r("22","")}o.1h="";o.21="";H P}9 16(){$("#8").r({2U:\'-\'+20((13/2),10)+\'p\',z:13+\'p\'});3(!(1V.1q.2Q&&1V.1q.2P<7)){$("#8").r({38:\'-\'+20((1a/2),10)+\'p\'})}}9 2p(a){6 b={};3(!a){H b}6 c=a.1B(/[;&]/);25(6 i=0;i * */ jQuery.fn.quicksearch = function( target, searchElems, options ) { // console.debug( "Quicksearch fn" ); var settings = { delay: 250, clearButton: false, highlightMatches: false, focusOnLoad: false, noSearchResultsIndicator: null }; if ( options ) $.extend( settings, options ); return jQuery(this).each( function() { // console.debug( "Creating a new quicksearch on %o for %o", this, searchElems ); new jQuery.quicksearch( this, searchElems, settings ); }); }; jQuery.quicksearch = function( searchBox, searchElems, settings ) { var timeout; var boxdiv = $(searchBox).parents('div').eq(0); function init() { setupKeyEventHandlers(); focusOnLoad(); }; function setupKeyEventHandlers() { // console.debug( "Hooking up the 'keypress' event to %o", searchBox ); $(searchBox). unbind( 'keyup' ). keyup( function(e) { return onSearchKey( e.keyCode ); }); $(searchBox). unbind( 'keypress' ). keypress( function(e) { switch( e.which ) { // Execute the search on Enter, Tab, or Newline case 9: case 13: case 10: clearTimeout( timeout ); e.preventDefault(); doQuickSearch(); break; // Allow backspace case 8: return true; break; // Only allow valid search characters default: return validQSChar( e.charCode ); } }); }; function focusOnLoad() { if ( !settings.focusOnLoad ) return false; $(searchBox).focus(); }; function onSearchKey ( code ) { clearTimeout( timeout ); // console.debug( "...scheduling search." ); timeout = setTimeout( doQuickSearch, settings.delay ); }; function validQSChar( code ) { var c = String.fromCharCode( code ); return ( (c == ':') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ); }; function doQuickSearch() { var searchText = searchBox.value; var pat = new RegExp( searchText, "im" ); var shownCount = 0; if ( settings.noSearchResultsIndicator ) { $('#' + settings.noSearchResultsIndicator).hide(); } // All elements start out hidden $(searchElems).each( function(index) { var str = $(this).text(); if ( pat.test(str) ) { shownCount += 1; $(this).fadeIn(); } else { $(this).hide(); } }); if ( shownCount == 0 && settings.noSearchResultsIndicator ) { $('#' + settings.noSearchResultsIndicator).slideDown(); } }; init(); }; PK!=ۏ6FF created.ridnu[Thu, 05 Dec 2019 17:59:32 -0500 lib/rack.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/showexceptions.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/etag.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/auth/basic.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/auth/digest/nonce.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/auth/digest/params.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/auth/digest/request.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/auth/digest/md5.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/auth/abstract/request.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/auth/abstract/handler.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/multipart/parser.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/multipart/generator.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/multipart/uploaded_file.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/request.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/tempfile_reaper.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/deflater.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/recursive.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/lobster.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/backports/uri/common_193.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/backports/uri/common_18.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/backports/uri/common_192.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/showstatus.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/response.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/head.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/runtime.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/content_type.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/utils.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/content_length.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/cascade.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/sendfile.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/mock.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/file.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/utils/okjson.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/server.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/lock.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/reloader.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/body_proxy.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/rewindable_input.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/directory.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler/webrick.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler/evented_mongrel.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler/scgi.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler/mongrel.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler/lsws.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler/cgi.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler/fastcgi.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler/swiftiplied_mongrel.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler/thin.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/methodoverride.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/chunked.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/nulllogger.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/session/pool.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/session/cookie.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/session/memcache.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/session/abstract/id.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/handler.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/builder.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/multipart.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/conditionalget.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/urlmap.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/mime.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/logger.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/lint.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/commonlogger.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/config.rb Thu, 05 Dec 2019 17:59:30 -0500 lib/rack/static.rb Thu, 05 Dec 2019 17:59:30 -0500 README.rdoc Thu, 05 Dec 2019 17:59:30 -0500 KNOWN-ISSUES Thu, 05 Dec 2019 17:59:30 -0500 HISTORY.md Thu, 05 Dec 2019 17:59:30 -0500 PK!ܽ11 Object.htmlnu[ Class: Object

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Object

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!h˟eeimages/tag_green.pngnu[PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˅IaOUÿ {bFcN4FMtn-=6c li4BH!(dX՗.U>BZERA\FTBXDP}!r^C2^@I`&tl $ɝ,S3MD.' 90NCӴY6)F?2m$ b @WH<Nt͐xj D"5v1of^gVfI.lfhě9<VOC|8i4>C8%JlGk8z#SmȉrXZ\@{x<.`^or ŌBx<^'j}U1}QWhT ]"kL|snێ# ~ߢK\}bx'BQ'{i^oPȲz].c)weSL|iW(SIENDB`PK!=Vimages/bullet_toggle_minus.pngnu[PNG  IHDR7gAMA7tEXtSoftwareAdobe ImageReadyqe<aIDAT(cπ2Q+/ދEp, %ւ)XC۱)XdB=6PMu][z+_70!IȓzS5IENDB`PK!Simages/bug.pngnu[PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˝OSQ\^[تtz% l$***2: iRp c0ąKw&&`44(eKɽwwrOX\HiscUQz@;քIdTaˀ)jC'يKT8=ʯ9ނ^zΘ1OFZ[W-Gz?&%*MGnN!aO>Nc[ɨX·0Nqg*1Sub|{g|fz)̾&\ 5\ 0 3i D;`|0>A?Tx4^`oqs`>ʦ`fCv@mX[r\At.)G[ Ì`N1)BWs+:NdsVa*DX.pB&B]H@T3@Pڏڠ wVP63yp-4 Ǽ $H'9{m@U$ZjCX:TgL::?[#{1P=.2F\iA-D 77qXIפb4kaAj% ͼj&Q˫H&s. `jKLE3*ΫX w6_l=@hߊv ,qqIENDB`PK!0 images/brick.pngnu[PNG  IHDR7gAMA7tEXtSoftwareAdobe ImageReadyqe<VIDAT?HTݝ^ٟ ju ɥpOhi/8ԩ!p*0Ў;}E,tnM2|13 "byK$i^NFDЙ;4eZ|Uj|jf^$ig)kYbIuKWPcJ'U>4MKB݆eSJtO9iԄ ʆn#2u` *_ R4+*BuϘMYU׷oAaLG۽kE|"2w9m[yGwSB3{er~㫹<{ @% @IENDB`PK!$Vimages/macFFBgHack.pngnu[PNG  IHDRcsBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS3FtEXtCreation Time7/16/07Z (IDATHA0!U[ GϱJJJJJJJJJYIENDB`PK!Zmmimages/page_green.pngnu[PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT?s~~TI!!bF ,H8b1a5l NQB b`^8MA~y*޿\)(0kJiΆIH q~{СMкOgԪ(2X2s,}O>};x3o}~Wtܠ$SjbjLEMa8y޿ww>JҪ*m*u=g6=W|vjz :@B(%UZ4\1mfj"jAƚ6hT*J VZJZ $@10PHZ(} )Be  @)zcԊe 02FHd#W?9Wi!Gc{sގl6IENDB`PK!(VVimages/page_white_text.pngnu[PNG  IHDR7gAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT1nSAǞ4A(ISp.KPp"QA7%1Ӣ;+Z######DWk=C?|Xj9昇SekMs9NNVG@kD)4hn.Q@nJ)1]:;1@ T:ti:I$fM-+g]^LvIENDB`PK!CCJUUimages/package.pngnu[PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8}Kh\u{g̝4L)B1>n\F)PAD QTWf!"؍` HC0ijC1ͳLfw(v!g}69)wyc/T4"Գ X8ѫ̛vכ*WGU}[E>7&tJiG+*rQE>{ `=9o/rorgaw=MЪUQVcƏ;}ź;qD>r 7jT1aU&m86l7KVio{Ǥ9sVԨ,O"aWūmptk.h-V}֯K*R\M- Юޡ'O'CU0)79Ms&3P#V 'w'ů N,op#LRi4Qj h]GS\;QƤBH`1@<Ѐd^{9] !"dlǁD @|0mp  Q a+kK7 "$ h$?$BrN#&Cif N7SV[6laL/HbF6tX=ֽɕد}GO|뻗zUC5rh8D>)4Vwͦ|"L\>2FΫ[^yjW?'q{gBio.ȧTctܲ^&IENDB`PK!(?Yimages/bullet_black.pngnu[PNG  IHDR7gAMA7tEXtSoftwareAdobe ImageReadyqe<eIDAT(cπ2 .R We7JaWА\ X]?XH^? 73`[*60H ڐsVIENDB`PK!Qimages/loadingAnimation.gifnu[GIF89a ! NETSCAPE2.0! ,  @Rihlp,tm#6N+rrD4h@FCjz]Lj]﹬R3-H$wPy |KI\K Q\]PI ~$ ~ J %:`@ XP@AO 2|(D**HE}lF=$Ƌ@\9L J()? ``C=4RO@>}5TDU^=UQH~Xe֫:|AoG4Q]V;ޙ  jUzҧ]$jQM ʆķ7721@ܒDH;܋%ЅqۛXMgNάgMWz!`dѥ]uja}a ݸ6;5լDzTh,5~z~@y[:3M7gG]q=@c5 4u흃5__9_AMtB\K ⵘ}" @lDiQu+baq&{#'LHjz"$& $B! ,  EI@*PR*;ò[Ll7DҎ%GI0)mIԲ`I}>ă}-RwFu}y|O(p*"rt{RA>( ^( "4 333..Чɞ v.*o 3u zz( D.z Ha рP*6=%8A%ϤH]JQ&2Lz녆Aɔ>50j( ]T.s *I@m:nTx^7}v(Hy!8/ 4^ֹGi`zA"?l8]'STҧX*3@XMS<@蜮-./Ay5|Uv۬ϰVr4<A:\4bmdvi{˿ӛW'7naq{"8V_u_^2_[koTpbp :M skx_"Vؓ! ,  %R4 yԬԢ\K٩l'#QZ0ՠVTyïe]U4f!Pc0zkW+_ ^ў`v"Ŋa@x:@O,ȬtK5zsRtH5y3ʥ>yz=3[/Z|&x @7nGdn B^|{ZCN3Z&$p{f;^C}Co %! ,  %$5,%:k.]#> B"ZRp]2Shk9E-e<ͩkGj6-twsz|mOQtix41 ) U"  BQ B)# B+u  )ێ #" pg߿=QǍPa Q*֑Xb<88l$Q,? y2=0յT#rΗ5 9`jLmgTJ2MWy6jukիKy0iP0JCg&(`oq]혗']u}C*  ^\sxaGtKpeÈa@jvlgVDz$ͣQ>mb16}4 @l`ѪzvsGt 2y֐/V+SNJ=^"+Y  09ڛ>0}Lj`abqO '8^Xd|5 [ahWY7֑W6!i!qHX&(@3&B! ,  Q$@RS" k; S]3X'+ζS tUik `m0c]wldt$v}k~zq,lryux?)B ; 00;+ ­G 0-g+ .z%$z +l(jx9hNt<; 8O7yxH#|bH$ѼLipȅѐ 2"-A(P$tj@{s(W$( =!u5(jmn wmĸoA@w/d1+:'l1f#|,z20Hg@1}թٯ[3S+|7Uǃ.{ P卵0ʶc=+PL03:~p'v{On<~)@uP6 k (àK'vK V`I9(ZLG!! ,  PeRN*',Ԣv*o<bKs M3k>oR sAE1fm):kvvM{wl rtqPm|uF~?W a3& A66 - 3- .,6o 3/h-o 'dzz&(CGo߉Oa9ќD= kOOEuj(ǑLʏTIR&K.H= ttI£B0E:qjԪPhY‰ ʾBFdÎT0@ܝK!Aݽ_aw9hP(!Ѣ,fʓmZ,rƝ[|.1鑣wZh%.:^mRi綽7V޿}c\u;o>oüu+],Ebd]/\.*h3;߯~ |HoXg6] !! ,  E9$#%5(,Ԓr(i0.݊`lXtD%ydJ6H^.pl[k=.˿(>Sx~gypv}lNtjx{e> ( ~~ -- ,-(Ĺ ' e -/p(u '" u GN šL1:I<9uG '9cɕ-Q$L'lD7UTTׄ tѦBU@%JJŪ)W?LSY bZvmމБ]xF0I{VXg|-BfE#|.@4OP4u8S g ֥_n;Ө՞(բQ)wǮ<.(ʳ2?eG|LՅ"x/-/y+,p=E1 dQٷ~2Kꔛ$r `m*YsC zFn ak}nnI#Q! ,  %R4Ԝ"CA,(~ں8׼دDA֐2hs݌+p]ˤObKw8^>uz`H~htkv"xm|1Z, -#51"1''[#, ,}, ' p#h1 w a"w #p"b1V-akcB)P@;]XqČ#N-A"߲SyrL4eMʚph\@eq/o D2(𯘳q s:gu@Fu+QAUӯZ#xbR4vG1 Mɻ;8FP`B۩3he11O~ ˟>z(C3A=\Z-ڇAa-qiSRYmG(1;Ž=dtqB[! ,  %dihlp,40T:Ԕn琘9␄\< P)JZ+^f(-N Ǥ4ant#o~$z|u#Svx@"'% #m# S%  $%§ #ְͽ$& A"%  $#H݃'/9BH EdOC)Lq#Fo gBbDIʤC'CRg̙G 4^M=F\dd3 X堙Kl٣̊@@T?}IVUT+ol|gr TeluӭޒvG]l<ݑsg_D )4EQ_i)Pi#!h Da %.@qMOQ `pnyHWC"$s* ]hp$V 8)oHHimages/wrench_orange.pngnu[PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˕kSQ8H)N]uA,wjazcbb6& Qcn^b4b2e l xW }$9Xt:$n"0T8J)N!h4ʉF|p8|2X,f[͵`0S~OZ% } iz=nHXt:4 "BrLRtv_T'-lu&f_uRl6 u]e 5~lޢnz{ejjUiw|}?$&x r|TN%*4Ç l;'T^ٗG <"pFୌw!yhݔeE6  ܙצ PJ:C\DW^,<<4 A ѹ]s6ޑIENDB`PK!7 images/zoom.pngnu[PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<FIDAT8ˍKHA̪-KC= CmfuP)DB"K$A etJZyum0}f~3#sL|!!|g-V9Q鎺c`TC8*5bF'R!DЋ kb^sP!Locgע≣.=^u֘[ 65޶FG ! P %wN5\q=(t@ȀѶ(t2)է"L?B2uXcYV$&a]ct< *Q1}E )hYҁ갎6` DXr<:=UR̞O98*}V&b==hցqف+;˜JT<A!C:̼}nAH~0bM36 +/痗sIĢ̾Ek J {v!=_MyKb]öa{6W03DÔ?R;c}s}Wb{{Jlff`[%nJs.Û/ZA8>>FP@>5}q$ {_Kx<B!y+qIEauuNS1stpppLMM;99G T/=/ LNNaOd2H$8;;9pzzZtxggp^W" bbbBU$A:-"WU9D6nnnJJUUqssd2X,&U]HtF'$fS4 x\>CvXZZdjr*^GQR)גct]l6GMr8d0e\SS$immMWp544zzzIpuu^u90_9>^WTT| P]]: $AWÃw{5nZZZ&c]5}EP^^`0,˃cccW/"֘kX YjIENDB`PK!bbimages/wrench.pngnu[PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˕oQ_[c+W.]хi5  g mJ[Fq#_)qո;,@{;upLTʙH$(Z XMɤni"\nt:}yD 0 \ ږIU4(r HMk̈_4_ziy'"[ n1rM_A`b=$Ik_p-qS~=li~3Bv"qZAԧ̸r[G]<&e!'ڸ67 yq$OX!=_~1Gs~EZQx&qWK3!ޤunkzGrjQnIENDB`PK!Errimages/date.pngnu[PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8˕RmkA~ԋK$5X% ǂ!#?P@PZ(*EA#ܹۙw:0;3ϼ@J f?WoL` OZ+M9cktyx D7гm\PSt]Io@#/د)[f^ѻ#dHkbG"uݿq\.Xc8YhH|r}/!FsRB(]jT5V?ZxYl6sd2QgwpdC2p8A厊*X,¢<}" W  8s"jR--tiM1eK lT*=L/F#C7~ -:MW1IENDB`PK!#۸PPimages/ruby.pngnu[PNG  IHDRagAMA7tEXtSoftwareAdobe ImageReadyqe<IDAT8͓KQ &*z( z24r!\e77V"x!bT7R*c <||:[WAD>9{Li'v%IID=z/;"\k޸)ku9x]2$W0= $QH>}F|`n6ϜϤkN7 >9LL(,.}>ּ^ OMM|%꿏:/T]F$ 6VW))t5FKòQq"rf y_Oa| pHJ*MTX8[^Dr-||[v(33!.44NJebʡrטu͚d+@ S[Ko~TKrjkoraPDPy5@Y?i܅Sg@'˼Zj_M5̻w. ;'5ڿ_IENDB`PK! ?4?4KNOWN-ISSUES.htmlnu[ File: KNOWN-ISSUES [rack-1.6.4 Documentation]

    Files

    Class Index [+]

    Quicksearch

    Known issues with Rack and ECMA-262

    • Many users expect the escape() function defined in ECMA-262 to be compatible with URI. Confusion is especially strong because the documentation for the escape function includes a reference to the URI specifications. ECMA-262 escape is not however a URI escape function, it is a javascript escape function, and is not fully compatible. Most notably, for characters outside of the BMP. Users should use the more correct encodeURI functions.

    Known issues with Rack and Web servers

    • Lighttpd sets wrong SCRIPT_NAME and PATH_INFO if you mount your FastCGI app at "/". This can be fixed by using this middleware:

      class LighttpdScriptNameFix
        def initialize(app)
          @app = app
        end
      
        def call(env)
          env["PATH_INFO"] = env["SCRIPT_NAME"].to_s + env["PATH_INFO"].to_s
          env["SCRIPT_NAME"] = ""
          @app.call(env)
        end
      end

      Of course, use this only when your app runs at "/".

      Since lighttpd 1.4.23, you also can use the "fix-root-scriptname" flag in fastcgi.server.

    Known conflicts regarding parameter parsing

    * Many users have differing opinions about parameter parsing. The current
      parameter parsers in Rack are based on a combination of the HTTP and CGI
      specs, and are intended to round-trip encoding and decoding. There are some
      choices that may be viewed as deficiencies, specifically:
       - Rack does not create implicit arrays for multiple instances of a parameter
       - Rack returns nil when a value is not given
       - Rack does not support multi-type keys in parameters
      These issues or choices, will not be fixed before 2.0, if at all. They are
      very major breaking changes. Users are free to write alternative parameter
      parsers, and their own Request and Response wrappers. Moreover, users are
      encouraged to do so.

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!$ Rack.htmlnu[ Module: Rack

    In Files

    Files

    Class/Module Index [+]

    Quicksearch

    Rack

    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.rb in your code.

    Public Class Methods

    release() click to toggle source

    Return the Rack release as a dotted string.

    # File lib/rack.rb, line 22
    def self.release
      "1.6.4"
    end
    version() click to toggle source

    Return the Rack protocol version as a dotted string.

    # File lib/rack.rb, line 17
    def self.version
      VERSION.join(".")
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!v,9696Rack/Session.htmlnu[ Module: Rack::Session

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!;[22+Rack/Multipart/MultipartPartLimitError.htmlnu[ Class: Rack::Multipart::MultipartPartLimitError

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Multipart::MultipartPartLimitError

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!O-eeRack/Multipart/Parser.htmlnu[ Class: Rack::Multipart::Parser

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Multipart::Parser

    Public Class Methods

    create(env) click to toggle source
    # File lib/rack/multipart/parser.rb, line 12
    def self.create(env)
      return DUMMY unless env['CONTENT_TYPE'] =~ MULTIPART
    
      io = env['rack.input']
      io.rewind
    
      content_length = env['CONTENT_LENGTH']
      content_length = content_length.to_i if content_length
    
      tempfile = env['rack.multipart.tempfile_factory'] ||
        lambda { |filename, content_type| Tempfile.new(["RackMultipart", ::File.extname(filename)]) }
      bufsize = env['rack.multipart.buffer_size'] || BUFSIZE
    
      new($1, io, content_length, env, tempfile, bufsize)
    end
    new(boundary, io, content_length, env, tempfile, bufsize) click to toggle source
    # File lib/rack/multipart/parser.rb, line 28
    def initialize(boundary, io, content_length, env, tempfile, bufsize)
      @buf            = ""
    
      if @buf.respond_to? :force_encoding
        @buf.force_encoding Encoding::ASCII_8BIT
      end
    
      @params         = Utils::KeySpaceConstrainedParams.new
      @boundary       = "--#{boundary}"
      @io             = io
      @content_length = content_length
      @boundary_size  = Utils.bytesize(@boundary) + EOL.size
      @env = env
      @tempfile       = tempfile
      @bufsize        = bufsize
    
      if @content_length
        @content_length -= @boundary_size
      end
    
      @rx = /(?:#{EOL})?#{Regexp.quote(@boundary)}(#{EOL}|--)/
      @full_boundary = @boundary + EOL
    end

    Public Instance Methods

    parse() click to toggle source
    # File lib/rack/multipart/parser.rb, line 52
    def parse
      fast_forward_to_first_boundary
    
      opened_files = 0
      loop do
    
        head, filename, content_type, name, body =
          get_current_head_and_filename_and_content_type_and_name_and_body
    
        if Utils.multipart_part_limit > 0
          opened_files += 1 if filename
          raise MultipartPartLimitError, 'Maximum file multiparts in content reached' if opened_files >= Utils.multipart_part_limit
        end
    
        # Save the rest.
        if i = @buf.index(rx)
          body << @buf.slice!(0, i)
          @buf.slice!(0, @boundary_size+2)
    
          @content_length = -1  if $1 == "--"
        end
    
        get_data(filename, body, content_type, name, head) do |data|
          tag_multipart_encoding(filename, content_type, name, data)
    
          Utils.normalize_params(@params, name, data)
        end
    
        # break if we're at the end of a buffer, but not if it is the end of a field
        break if (@buf.empty? && $1 != EOL) || @content_length == -1
      end
    
      @io.rewind
    
      @params.to_params_hash
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!\HHRack/Multipart/Generator.htmlnu[ Class: Rack::Multipart::Generator

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Multipart::Generator

    Public Class Methods

    new(params, first = true) click to toggle source
    # File lib/rack/multipart/generator.rb, line 4
    def initialize(params, first = true)
      @params, @first = params, first
    
      if @first && !@params.is_a?(Hash)
        raise ArgumentError, "value must be a Hash"
      end
    end

    Public Instance Methods

    dump() click to toggle source
    # File lib/rack/multipart/generator.rb, line 12
    def dump
      return nil if @first && !multipart?
      return flattened_params if !@first
    
      flattened_params.map do |name, file|
        if file.respond_to?(:original_filename)
          ::File.open(file.path, "rb") do |f|
            f.set_encoding(Encoding::BINARY) if f.respond_to?(:set_encoding)
            content_for_tempfile(f, file, name)
          end
        else
          content_for_other(file, name)
        end
      end.join + "--#{MULTIPART_BOUNDARY}--\r"
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!X$R$R Rack/Multipart/UploadedFile.htmlnu[ Class: Rack::Multipart::UploadedFile

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Multipart::UploadedFile

    Attributes

    content_type[RW]

    The content type of the "uploaded" file

    original_filename[R]

    The filename, not including the path, of the "uploaded" file

    Public Class Methods

    new(path, content_type = "text/plain", binary = false) click to toggle source
    # File lib/rack/multipart/uploaded_file.rb, line 10
    def initialize(path, content_type = "text/plain", binary = false)
      raise "#{path} file does not exist" unless ::File.exist?(path)
      @content_type = content_type
      @original_filename = ::File.basename(path)
      @tempfile = Tempfile.new([@original_filename, ::File.extname(path)])
      @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
      @tempfile.binmode if binary
      FileUtils.copy_file(path, @tempfile.path)
    end

    Public Instance Methods

    local_path() click to toggle source
    Alias for: path
    path() click to toggle source
    # File lib/rack/multipart/uploaded_file.rb, line 20
    def path
      @tempfile.path
    end
    Also aliased as: local_path
    respond_to?(*args) click to toggle source
    # File lib/rack/multipart/uploaded_file.rb, line 25
    def respond_to?(*args)
      super or @tempfile.respond_to?(*args)
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!lG$88Rack/Auth.htmlnu[ Module: Rack::Auth

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!.zޏޏRack/Response.htmlnu[ Class: Rack::Response

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Response

    Rack::Response provides a convenient interface to create a Rack response.

    It allows setting of headers and cookies, and provides useful defaults (a OK response containing HTML).

    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.

    Attributes

    body[RW]
    header[R]
    headers[R]
    length[RW]
    status[RW]

    Public Class Methods

    new(body=[], status=200, header={}) click to toggle source
    # File lib/rack/response.rb, line 25
    def initialize(body=[], status=200, header={})
      @status = status.to_i
      @header = Utils::HeaderHash.new.merge(header)
    
      @chunked = CHUNKED == @header[TRANSFER_ENCODING]
      @writer  = lambda { |x| @body << x }
      @block   = nil
      @length  = 0
    
      @body = []
    
      if body.respond_to? :to_str
        write body.to_str
      elsif body.respond_to?(:each)
        body.each { |part|
          write part.to_s
        }
      else
        raise TypeError, "stringable or iterable required"
      end
    
      yield self  if block_given?
    end

    Public Instance Methods

    [](key) click to toggle source
    # File lib/rack/response.rb, line 52
    def [](key)
      header[key]
    end
    []=(key, value) click to toggle source
    # File lib/rack/response.rb, line 56
    def []=(key, value)
      header[key] = value
    end
    close() click to toggle source
    # File lib/rack/response.rb, line 107
    def close
      body.close if body.respond_to?(:close)
    end
    each(&callback) click to toggle source
    # File lib/rack/response.rb, line 88
    def each(&callback)
      @body.each(&callback)
      @writer = callback
      @block.call(self)  if @block
    end
    empty?() click to toggle source
    # File lib/rack/response.rb, line 111
    def empty?
      @block == nil && @body.empty?
    end
    finish(&block) click to toggle source
    # File lib/rack/response.rb, line 73
    def finish(&block)
      @block = block
    
      if [204, 205, 304].include?(status.to_i)
        header.delete CONTENT_TYPE
        header.delete CONTENT_LENGTH
        close
        [status.to_i, header, []]
      else
        [status.to_i, header, BodyProxy.new(self){}]
      end
    end
    Also aliased as: to_a, to_ary
    redirect(target, status=302) click to toggle source
    # File lib/rack/response.rb, line 68
    def redirect(target, status=302)
      self.status = status
      self["Location"] = target
    end
    to_a(&block) click to toggle source
    Alias for: finish
    to_ary(&block) click to toggle source
    Alias for: finish
    write(str) click to toggle source

    Append to body and update Content-Length.

    NOTE: Do not mix write and direct body access!

    # File lib/rack/response.rb, line 98
    def write(str)
      s = str.to_s
      @length += Rack::Utils.bytesize(s) unless @chunked
      @writer.call s
    
      header[CONTENT_LENGTH] = @length.to_s unless @chunked
      str
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!7BBRack/TempfileReaper.htmlnu[ Class: Rack::TempfileReaper

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::TempfileReaper

    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 groups.google.com/forum/#!searchin/rack-devel/temp/rack-devel/brK8eh-MByw/sw61oJJCGRMJ

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/tempfile_reaper.rb, line 9
    def initialize(app)
      @app = app
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/tempfile_reaper.rb, line 13
    def call(env)
      env['rack.tempfiles'] ||= []
      status, headers, body = @app.call(env)
      body_proxy = BodyProxy.new(body) do
        env['rack.tempfiles'].each { |f| f.close! } unless env['rack.tempfiles'].nil?
      end
      [status, headers, body_proxy]
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK! "H"HRack/ContentLength.htmlnu[ Class: Rack::ContentLength

    Parent

    Methods

    Included Modules

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::ContentLength

    Sets the Content-Length header on responses with fixed-length bodies.

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/content_length.rb, line 10
    def initialize(app)
      @app = app
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/content_length.rb, line 14
    def call(env)
      status, headers, body = @app.call(env)
      headers = HeaderHash.new(headers)
    
      if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
         !headers[CONTENT_LENGTH] &&
         !headers['Transfer-Encoding'] &&
         body.respond_to?(:to_ary)
    
        obody = body
        body, length = [], 0
        obody.each { |part| body << part; length += bytesize(part) }
    
        body = BodyProxy.new(body) do
          obody.close if obody.respond_to?(:close)
        end
    
        headers[CONTENT_LENGTH] = length.to_s
      end
    
      [status, headers, body]
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!Ns)KKRack/Chunked.htmlnu[ Class: Rack::Chunked

    Parent

    Namespace

    Included Modules

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Chunked

    Middleware that applies chunked transfer encoding to response bodies when the response does not include a Content-Length header.

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/chunked.rb, line 38
    def initialize(app)
      @app = app
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/chunked.rb, line 53
    def call(env)
      status, headers, body = @app.call(env)
      headers = HeaderHash.new(headers)
    
      if ! chunkable_version?(env['HTTP_VERSION']) ||
         STATUS_WITH_NO_ENTITY_BODY.include?(status) ||
         headers[CONTENT_LENGTH] ||
         headers['Transfer-Encoding']
        [status, headers, body]
      else
        headers.delete(CONTENT_LENGTH)
        headers['Transfer-Encoding'] = 'chunked'
        [status, headers, Body.new(body)]
      end
    end
    chunkable_version?(ver) click to toggle source

    pre-HTTP/1.0 (informally "HTTP/0.9") HTTP requests did not have a version (nor response headers)

    # File lib/rack/chunked.rb, line 44
    def chunkable_version?(ver)
      case ver
      when "HTTP/1.0", nil, "HTTP/0.9"
        false
      else
        true
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!e#Jg^^Rack/Sendfile.htmlnu[ Class: Rack::Sendfile

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Sendfile

    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::File 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: wiki.codemongers.com/NginxXSendfile

    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: redmine.lighttpd.net/wiki/lighttpd/Docs:ModProxyCore

    Apache

    X-Sendfile is supported under Apache 2.x using a separate module:

    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.

    Constants

    F

    Public Class Methods

    new(app, variation=nil, mappings=[]) click to toggle source
    # File lib/rack/sendfile.rb, line 104
    def initialize(app, variation=nil, mappings=[])
      @app = app
      @variation = variation
      @mappings = mappings.map do |internal, external|
        [/^#{internal}/, external]
      end
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/sendfile.rb, line 112
    def call(env)
      status, headers, body = @app.call(env)
      if body.respond_to?(:to_path)
        case type = variation(env)
        when 'X-Accel-Redirect'
          path = F.expand_path(body.to_path)
          if url = map_accel_path(env, path)
            headers[CONTENT_LENGTH] = '0'
            headers[type] = url
            obody = body
            body = 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'
          path = F.expand_path(body.to_path)
          headers[CONTENT_LENGTH] = '0'
          headers[type] = path
          obody = body
          body = Rack::BodyProxy.new([]) do
            obody.close if obody.respond_to?(:close)
          end
        when '', nil
        else
          env['rack.errors'].puts "Unknown x-sendfile variation: '#{type}'.\n"
        end
      end
      [status, headers, body]
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!-H.LLRack/ShowStatus.htmlnu[ Class: Rack::ShowStatus

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::ShowStatus

    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.

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/showstatus.rb, line 14
    def initialize(app)
      @app = app
      @template = ERB.new(TEMPLATE)
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/showstatus.rb, line 19
    def call(env)
      status, headers, body = @app.call(env)
      headers = Utils::HeaderHash.new(headers)
      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 on
        # Ruby 1.9.3.  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 on
        # Ruby 1.9.3.  Yes, it is dumb, but I don't like Ruby yelling at me.
        detail = detail = env["rack.showstatus.detail"] || message
    
        body = @template.result(binding)
        size = Rack::Utils.bytesize(body)
        [status, headers.merge(CONTENT_TYPE => "text/html", CONTENT_LENGTH => size.to_s), [body]]
      else
        [status, headers, body]
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!H22$Rack/Handler/SwiftipliedMongrel.htmlnu[ Class: Rack::Handler::SwiftipliedMongrel

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler::SwiftipliedMongrel

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!&HM{M{Rack/Handler/Mongrel.htmlnu[ Class: Rack::Handler::Mongrel

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler::Mongrel

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/handler/mongrel.rb, line 57
    def initialize(app)
      @app = app
    end
    run(app, options={}) click to toggle source
    # File lib/rack/handler/mongrel.rb, line 9
    def self.run(app, options={})
      environment  = ENV['RACK_ENV'] || 'development'
      default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
    
      server = ::Mongrel::HttpServer.new(
        options[:Host]           || default_host,
        options[:Port]           || 8080,
        options[:num_processors] || 950,
        options[:throttle]       || 0,
        options[:timeout]        || 60)
      # Acts like Rack::URLMap, utilizing Mongrel's own path finding methods.
      # Use is similar to #run, replacing the app argument with a hash of
      # { path=>app, ... } or an instance of Rack::URLMap.
      if options[:map]
        if app.is_a? Hash
          app.each do |path, appl|
            path = '/'+path unless path[0] == //
            server.register(path, Rack::Handler::Mongrel.new(appl))
          end
        elsif app.is_a? URLMap
          app.instance_variable_get(:@mapping).each do |(host, path, appl)|
           next if !host.nil? && !options[:Host].nil? && options[:Host] != host
           path = '/'+path unless path[0] == //
           server.register(path, Rack::Handler::Mongrel.new(appl))
          end
        else
          raise ArgumentError, "first argument should be a Hash or URLMap"
        end
      else
        server.register('/', Rack::Handler::Mongrel.new(app))
      end
      yield server  if block_given?
      server.run.join
    end
    valid_options() click to toggle source
    # File lib/rack/handler/mongrel.rb, line 44
    def self.valid_options
      environment  = ENV['RACK_ENV'] || 'development'
      default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
    
      {
        "Host=HOST" => "Hostname to listen on (default: #{default_host})",
        "Port=PORT" => "Port to listen on (default: 8080)",
        "Processors=N" => "Number of concurrent processors to accept (default: 950)",
        "Timeout=N" => "Time before a request is dropped for inactivity (default: 60)",
        "Throttle=N" => "Throttle time between socket.accept calls in hundredths of a second (default: 0)",
      }
    end

    Public Instance Methods

    process(request, response) click to toggle source
    # File lib/rack/handler/mongrel.rb, line 61
    def process(request, response)
      env = Hash[request.params]
      env.delete "HTTP_CONTENT_TYPE"
      env.delete "HTTP_CONTENT_LENGTH"
    
      env["SCRIPT_NAME"] = ""  if env["SCRIPT_NAME"] == "/"
    
      rack_input = request.body || StringIO.new('')
      rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
    
      env.update({"rack.version" => Rack::VERSION,
                   "rack.input" => rack_input,
                   "rack.errors" => $stderr,
    
                   "rack.multithread" => true,
                   "rack.multiprocess" => false, # ???
                   "rack.run_once" => false,
    
                   "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
                 })
      env[QUERY_STRING] ||= ""
    
      status, headers, body = @app.call(env)
    
      begin
        response.status = status.to_i
        response.send_status(nil)
    
        headers.each { |k, vs|
          vs.split("\n").each { |v|
            response.header[k] = v
          }
        }
        response.send_header
    
        body.each { |part|
          response.write part
          response.socket.flush
        }
      ensure
        body.close  if body.respond_to? :close
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!1hhRack/Handler/SCGI.htmlnu[ Class: Rack::Handler::SCGI

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler::SCGI

    Attributes

    app[RW]

    Public Class Methods

    new(settings = {}) click to toggle source
    # File lib/rack/handler/scgi.rb, line 29
    def initialize(settings = {})
      @app = settings[:app]
      super(settings)
    end
    run(app, options=nil) click to toggle source
    # File lib/rack/handler/scgi.rb, line 11
    def self.run(app, options=nil)
      options[:Socket] = UNIXServer.new(options[:File]) if options[:File]
      new(options.merge(:app=>app,
                        :host=>options[:Host],
                        :port=>options[:Port],
                        :socket=>options[:Socket])).listen
    end
    valid_options() click to toggle source
    # File lib/rack/handler/scgi.rb, line 19
    def self.valid_options
      environment  = ENV['RACK_ENV'] || 'development'
      default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
    
      {
        "Host=HOST" => "Hostname to listen on (default: #{default_host})",
        "Port=PORT" => "Port to listen on (default: 8080)",
      }
    end

    Public Instance Methods

    process_request(request, input_body, socket) click to toggle source
    # File lib/rack/handler/scgi.rb, line 34
    def process_request(request, input_body, socket)
      env = Hash[request]
      env.delete "HTTP_CONTENT_TYPE"
      env.delete "HTTP_CONTENT_LENGTH"
      env["REQUEST_PATH"], env[QUERY_STRING] = env["REQUEST_URI"].split('?', 2)
      env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
      env[PATH_INFO] = env["REQUEST_PATH"]
      env["QUERY_STRING"] ||= ""
      env["SCRIPT_NAME"] = ""
    
      rack_input = StringIO.new(input_body)
      rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
    
      env.update({"rack.version" => Rack::VERSION,
                   "rack.input" => rack_input,
                   "rack.errors" => $stderr,
                   "rack.multithread" => true,
                   "rack.multiprocess" => true,
                   "rack.run_once" => false,
    
                   "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
                 })
      status, headers, body = app.call(env)
      begin
        socket.write("Status: #{status}\r\n")
        headers.each do |k, vs|
          vs.split("\n").each { |v| socket.write("#{k}: #{v}\r\n")}
        end
        socket.write("\r\n")
        body.each {|s| socket.write(s)}
      ensure
        body.close if body.respond_to? :close
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!07zzRack/Handler/WEBrick.htmlnu[ Class: Rack::Handler::WEBrick

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler::WEBrick

    Public Class Methods

    new(server, app) click to toggle source
    # File lib/rack/handler/webrick.rb, line 52
    def initialize(server, app)
      super server
      @app = app
    end
    run(app, options={}) click to toggle source
    # File lib/rack/handler/webrick.rb, line 25
    def self.run(app, options={})
      environment  = ENV['RACK_ENV'] || 'development'
      default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
    
      options[:BindAddress] = options.delete(:Host) || default_host
      options[:Port] ||= 8080
      @server = ::WEBrick::HTTPServer.new(options)
      @server.mount "/", Rack::Handler::WEBrick, app
      yield @server  if block_given?
      @server.start
    end
    shutdown() click to toggle source
    # File lib/rack/handler/webrick.rb, line 47
    def self.shutdown
      @server.shutdown
      @server = nil
    end
    valid_options() click to toggle source
    # File lib/rack/handler/webrick.rb, line 37
    def self.valid_options
      environment  = ENV['RACK_ENV'] || 'development'
      default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
    
      {
        "Host=HOST" => "Hostname to listen on (default: #{default_host})",
        "Port=PORT" => "Port to listen on (default: 8080)",
      }
    end

    Public Instance Methods

    service(req, res) click to toggle source
    # File lib/rack/handler/webrick.rb, line 57
    def service(req, res)
      res.rack = true
      env = req.meta_vars
      env.delete_if { |k, v| v.nil? }
    
      rack_input = StringIO.new(req.body.to_s)
      rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
    
      env.update({"rack.version" => Rack::VERSION,
                   "rack.input" => rack_input,
                   "rack.errors" => $stderr,
    
                   "rack.multithread" => true,
                   "rack.multiprocess" => false,
                   "rack.run_once" => false,
    
                   "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http",
    
                   "rack.hijack?" => true,
                   "rack.hijack" => lambda { raise NotImplementedError, "only partial hijack is supported."},
                   "rack.hijack_io" => nil,
                 })
    
      env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
      env[QUERY_STRING] ||= ""
      unless env[PATH_INFO] == ""
        path, n = req.request_uri.path, env["SCRIPT_NAME"].length
        env[PATH_INFO] = path[n, path.length-n]
      end
      env["REQUEST_PATH"] ||= [env["SCRIPT_NAME"], env[PATH_INFO]].join
    
      status, headers, body = @app.call(env)
      begin
        res.status = status.to_i
        headers.each { |k, vs|
          next if k.downcase == "rack.hijack"
    
          if k.downcase == "set-cookie"
            res.cookies.concat vs.split("\n")
          else
            # Since WEBrick won't accept repeated headers,
            # merge the values per RFC 1945 section 4.2.
            res[k] = vs.split("\n").join(", ")
          end
        }
    
        io_lambda = headers["rack.hijack"]
        if io_lambda
          rd, wr = IO.pipe
          res.body = rd
          res.chunked = true
          io_lambda.call wr
        elsif body.respond_to?(:to_path)
          res.body = ::File.open(body.to_path, 'rb')
        else
          body.each { |part|
            res.body << part
          }
        end
      ensure
        body.close  if body.respond_to? :close
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK! t.ZZRack/Handler/CGI.htmlnu[ Class: Rack::Handler::CGI

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler::CGI

    Public Class Methods

    run(app, options=nil) click to toggle source
    # File lib/rack/handler/cgi.rb, line 7
    def self.run(app, options=nil)
      $stdin.binmode
      serve app
    end
    send_body(body) click to toggle source
    # File lib/rack/handler/cgi.rb, line 53
    def self.send_body(body)
      body.each { |part|
        $stdout.print part
        $stdout.flush
      }
    end
    send_headers(status, headers) click to toggle source
    # File lib/rack/handler/cgi.rb, line 42
    def self.send_headers(status, headers)
      $stdout.print "Status: #{status}\r\n"
      headers.each { |k, vs|
        vs.split("\n").each { |v|
          $stdout.print "#{k}: #{v}\r\n"
        }
      }
      $stdout.print "\r\n"
      $stdout.flush
    end
    serve(app) click to toggle source
    # File lib/rack/handler/cgi.rb, line 12
    def self.serve(app)
      env = ENV.to_hash
      env.delete "HTTP_CONTENT_LENGTH"
    
      env["SCRIPT_NAME"] = ""  if env["SCRIPT_NAME"] == "/"
    
      env.update({"rack.version" => Rack::VERSION,
                   "rack.input" => Rack::RewindableInput.new($stdin),
                   "rack.errors" => $stderr,
    
                   "rack.multithread" => false,
                   "rack.multiprocess" => true,
                   "rack.run_once" => true,
    
                   "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
                 })
    
      env[QUERY_STRING]   ||= ""
      env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
      env["REQUEST_PATH"] ||= "/"
    
      status, headers, body = app.call(env)
      begin
        send_headers status, headers
        send_body body
      ensure
        body.close  if body.respond_to? :close
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!S22 Rack/Handler/EventedMongrel.htmlnu[ Class: Rack::Handler::EventedMongrel

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler::EventedMongrel

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!kw[w[Rack/Handler/LSWS.htmlnu[ Class: Rack::Handler::LSWS

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler::LSWS

    Public Class Methods

    run(app, options=nil) click to toggle source
    # File lib/rack/handler/lsws.rb, line 8
    def self.run(app, options=nil)
      while LSAPI.accept != nil
        serve app
      end
    end
    send_body(body) click to toggle source
    # File lib/rack/handler/lsws.rb, line 53
    def self.send_body(body)
      body.each { |part|
        print part
        STDOUT.flush
      }
    end
    send_headers(status, headers) click to toggle source
    # File lib/rack/handler/lsws.rb, line 43
    def self.send_headers(status, headers)
      print "Status: #{status}\r\n"
      headers.each { |k, vs|
        vs.split("\n").each { |v|
          print "#{k}: #{v}\r\n"
        }
      }
      print "\r\n"
      STDOUT.flush
    end
    serve(app) click to toggle source
    # File lib/rack/handler/lsws.rb, line 13
    def self.serve(app)
      env = ENV.to_hash
      env.delete "HTTP_CONTENT_LENGTH"
      env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
    
      rack_input = RewindableInput.new($stdin.read.to_s)
    
      env.update(
        "rack.version" => Rack::VERSION,
        "rack.input" => rack_input,
        "rack.errors" => $stderr,
        "rack.multithread" => false,
        "rack.multiprocess" => true,
        "rack.run_once" => false,
        "rack.url_scheme" => ["yes", "on", "1"].include?(ENV["HTTPS"]) ? "https" : "http"
      )
    
      env[QUERY_STRING]   ||= ""
      env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
      env["REQUEST_PATH"] ||= "/"
      status, headers, body = app.call(env)
      begin
        send_headers status, headers
        send_body body
      ensure
        body.close if body.respond_to? :close
      end
    ensure
      rack_input.close
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!8҄mmRack/Handler/FastCGI.htmlnu[ Class: Rack::Handler::FastCGI

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler::FastCGI

    Public Class Methods

    run(app, options={}) click to toggle source
    # File lib/rack/handler/fastcgi.rb, line 21
    def self.run(app, options={})
      if options[:File]
        STDIN.reopen(UNIXServer.new(options[:File]))
      elsif options[:Port]
        STDIN.reopen(TCPServer.new(options[:Host], options[:Port]))
      end
      FCGI.each { |request|
        serve request, app
      }
    end
    send_body(out, body) click to toggle source
    # File lib/rack/handler/fastcgi.rb, line 93
    def self.send_body(out, body)
      body.each { |part|
        out.print part
        out.flush
      }
    end
    send_headers(out, status, headers) click to toggle source
    # File lib/rack/handler/fastcgi.rb, line 82
    def self.send_headers(out, status, headers)
      out.print "Status: #{status}\r\n"
      headers.each { |k, vs|
        vs.split("\n").each { |v|
          out.print "#{k}: #{v}\r\n"
        }
      }
      out.print "\r\n"
      out.flush
    end
    serve(request, app) click to toggle source
    # File lib/rack/handler/fastcgi.rb, line 43
    def self.serve(request, app)
      env = request.env
      env.delete "HTTP_CONTENT_LENGTH"
    
      env["SCRIPT_NAME"] = ""  if env["SCRIPT_NAME"] == "/"
    
      rack_input = RewindableInput.new(request.in)
    
      env.update({"rack.version" => Rack::VERSION,
                   "rack.input" => rack_input,
                   "rack.errors" => request.err,
    
                   "rack.multithread" => false,
                   "rack.multiprocess" => true,
                   "rack.run_once" => false,
    
                   "rack.url_scheme" => ["yes", "on", "1"].include?(env["HTTPS"]) ? "https" : "http"
                 })
    
      env[QUERY_STRING]   ||= ""
      env["HTTP_VERSION"] ||= env["SERVER_PROTOCOL"]
      env["REQUEST_PATH"] ||= "/"
      env.delete "CONTENT_TYPE"  if env["CONTENT_TYPE"] == ""
      env.delete "CONTENT_LENGTH"  if env["CONTENT_LENGTH"] == ""
    
      begin
        status, headers, body = app.call(env)
        begin
          send_headers request.out, status, headers
          send_body request.out, body
        ensure
          body.close  if body.respond_to? :close
        end
      ensure
        rack_input.close
        request.finish
      end
    end
    valid_options() click to toggle source
    # File lib/rack/handler/fastcgi.rb, line 32
    def self.valid_options
      environment  = ENV['RACK_ENV'] || 'development'
      default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
    
      {
        "Host=HOST" => "Hostname to listen on (default: #{default_host})",
        "Port=PORT" => "Port to listen on (default: 8080)",
        "File=PATH" => "Creates a Domain socket at PATH instead of a TCP socket. Ignores Host and Port if set.",
      }
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!b$JJRack/Handler/Thin.htmlnu[ Class: Rack::Handler::Thin

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler::Thin

    Public Class Methods

    run(app, options={}) click to toggle source
    # File lib/rack/handler/thin.rb, line 8
    def self.run(app, options={})
      environment  = ENV['RACK_ENV'] || 'development'
      default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
    
      host = options.delete(:Host) || default_host
      port = options.delete(:Port) || 8080
      args = [host, port, app, options]
      # Thin versions below 0.8.0 do not support additional options
      args.pop if ::Thin::VERSION::MAJOR < 1 && ::Thin::VERSION::MINOR < 8
      server = ::Thin::Server.new(*args)
      yield server if block_given?
      server.start
    end
    valid_options() click to toggle source
    # File lib/rack/handler/thin.rb, line 22
    def self.valid_options
      environment  = ENV['RACK_ENV'] || 'development'
      default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
    
      {
        "Host=HOST" => "Hostname to listen on (default: #{default_host})",
        "Port=PORT" => "Port to listen on (default: 8080)",
      }
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!kqB}}Rack/Utils/HeaderHash.htmlnu[ Class: Rack::Utils::HeaderHash

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils::HeaderHash

    A case-insensitive Hash that preserves the original case of a header when set.

    Public Class Methods

    new(hash={}) click to toggle source
    # File lib/rack/utils.rb, line 477
    def self.new(hash={})
      HeaderHash === hash ? hash : super(hash)
    end
    new(hash={}) click to toggle source
    # File lib/rack/utils.rb, line 481
    def initialize(hash={})
      super()
      @names = {}
      hash.each { |k, v| self[k] = v }
    end

    Public Instance Methods

    [](k) click to toggle source
    # File lib/rack/utils.rb, line 499
    def [](k)
      super(k) || super(@names[k.downcase])
    end
    []=(k, v) click to toggle source
    # File lib/rack/utils.rb, line 503
    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
    delete(k) click to toggle source
    # File lib/rack/utils.rb, line 510
    def delete(k)
      canonical = k.downcase
      result = super @names.delete(canonical)
      @names.delete_if { |name,| name.downcase == canonical }
      result
    end
    each() click to toggle source
    # File lib/rack/utils.rb, line 487
    def each
      super do |k, v|
        yield(k, v.respond_to?(:to_ary) ? v.to_ary.join("\n") : v)
      end
    end
    has_key?(k) click to toggle source
    Alias for: include?
    include?(k) click to toggle source
    # File lib/rack/utils.rb, line 517
    def include?(k)
      @names.include?(k) || @names.include?(k.downcase)
    end
    Also aliased as: has_key?, member?, key?
    key?(k) click to toggle source
    Alias for: include?
    member?(k) click to toggle source
    Alias for: include?
    merge(other) click to toggle source
    # File lib/rack/utils.rb, line 530
    def merge(other)
      hash = dup
      hash.merge! other
    end
    merge!(other) click to toggle source
    # File lib/rack/utils.rb, line 525
    def merge!(other)
      other.each { |k, v| self[k] = v }
      self
    end
    replace(other) click to toggle source
    # File lib/rack/utils.rb, line 535
    def replace(other)
      clear
      other.each { |k, v| self[k] = v }
      self
    end
    to_hash() click to toggle source
    # File lib/rack/utils.rb, line 493
    def to_hash
      hash = {}
      each { |k,v| hash[k] = v }
      hash
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!33"Rack/Utils/ParameterTypeError.htmlnu[ Class: Rack::Utils::ParameterTypeError

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils::ParameterTypeError

    ParameterTypeError is the error that is raised when incoming structural parameters (parsed by parse_nested_query) contain conflicting types.

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK![ ^Z^ZRack/Utils/OkJson.htmlnu[ Module: Rack::Utils::OkJson

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils::OkJson

    Public Instance Methods

    decode(s) click to toggle source

    Decodes a json document in string s and returns the corresponding ruby value. String s must be valid UTF-8. If you have a string in some other encoding, convert it first.

    String values in the resulting structure will be UTF-8.

    # File lib/rack/utils/okjson.rb, line 42
    def decode(s)
      ts = lex(s)
      v, ts = textparse(ts)
      if ts.length > 0
        raise Error, 'trailing garbage'
      end
      v
    end
    encode(x) click to toggle source

    Encodes x into a json text. It may contain only Array, Hash, String, Numeric, true, false, nil. (Note, this list excludes Symbol.) X itself must be an Array or a Hash. No other value can be encoded, and an error will be raised if x contains any other value, such as Nan, Infinity, Symbol, and Proc, or if a Hash key is not a String. Strings contained in x must be valid UTF-8.

    # File lib/rack/utils/okjson.rb, line 61
    def encode(x)
      case x
      when Hash    then objenc(x)
      when Array   then arrenc(x)
      else
        raise Error, 'root value must be an Array or a Hash'
      end
    end
    valenc(x) click to toggle source
    # File lib/rack/utils/okjson.rb, line 71
    def valenc(x)
      case x
      when Hash    then objenc(x)
      when Array   then arrenc(x)
      when String  then strenc(x)
      when Numeric then numenc(x)
      when true    then "true"
      when false   then "false"
      when nil     then "null"
      else
        raise Error, "cannot encode #{x.class}: #{x.inspect}"
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!D0303%Rack/Utils/InvalidParameterError.htmlnu[ Class: Rack::Utils::InvalidParameterError

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils::InvalidParameterError

    InvalidParameterError is the error that is raised when incoming structural parameters (parsed by parse_nested_query) contain invalid format or byte sequence.

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!c~Ѱ33Rack/Utils/OkJson/Error.htmlnu[ Class: Rack::Utils::OkJson::Error

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils::OkJson::Error

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!_33 Rack/Utils/OkJson/Utf8Error.htmlnu[ Class: Rack::Utils::OkJson::Utf8Error

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils::OkJson::Utf8Error

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!s'NNRack/Utils/Context.htmlnu[ Class: Rack::Utils::Context

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils::Context

    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.

    Attributes

    app[R]
    for[R]

    Public Class Methods

    new(app_f, app_r) click to toggle source
    # File lib/rack/utils.rb, line 456
    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

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/utils.rb, line 461
    def call(env)
      @for.context(env, @app)
    end
    context(env, app=@app) click to toggle source
    # File lib/rack/utils.rb, line 469
    def context(env, app=@app)
      recontext(app).call(env)
    end
    recontext(app) click to toggle source
    # File lib/rack/utils.rb, line 465
    def recontext(app)
      self.class.new(@for, app)
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!eڄ_V_V)Rack/Utils/KeySpaceConstrainedParams.htmlnu[ Class: Rack::Utils::KeySpaceConstrainedParams

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils::KeySpaceConstrainedParams

    Public Class Methods

    new(limit = Utils.key_space_limit) click to toggle source
    # File lib/rack/utils.rb, line 543
    def initialize(limit = Utils.key_space_limit)
      @limit  = limit
      @size   = 0
      @params = {}
    end

    Public Instance Methods

    [](key) click to toggle source
    # File lib/rack/utils.rb, line 549
    def [](key)
      @params[key]
    end
    []=(key, value) click to toggle source
    # File lib/rack/utils.rb, line 553
    def []=(key, value)
      @size += key.size if key && !@params.key?(key)
      raise RangeError, 'exceeded available parameter key space' if @size > @limit
      @params[key] = value
    end
    key?(key) click to toggle source
    # File lib/rack/utils.rb, line 559
    def key?(key)
      @params.key?(key)
    end
    to_params_hash() click to toggle source
    # File lib/rack/utils.rb, line 563
    def to_params_hash
      hash = @params
      hash.keys.each do |key|
        value = hash[key]
        if value.kind_of?(self.class)
          if value.object_id == self.object_id
            hash[key] = hash
          else
            hash[key] = value.to_params_hash
          end
        elsif value.kind_of?(Array)
          value.map! {|x| x.kind_of?(self.class) ? x.to_params_hash : x}
        end
      end
      hash
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!%VVRack/Cascade.htmlnu[ Class: Rack::Cascade

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Cascade

    Rack::Cascade tries a request on several apps, and returns the first response that is not 404 or 405 (or in a list of configurable status codes).

    Constants

    NotFound

    Attributes

    apps[R]

    Public Class Methods

    new(apps, catch=[404, 405]) click to toggle source
    # File lib/rack/cascade.rb, line 11
    def initialize(apps, catch=[404, 405])
      @apps = []; @has_app = {}
      apps.each { |app| add app }
    
      @catch = {}
      [*catch].each { |status| @catch[status] = true }
    end

    Public Instance Methods

    <<(app) click to toggle source
    Alias for: add
    add(app) click to toggle source
    # File lib/rack/cascade.rb, line 41
    def add(app)
      @has_app[app] = true
      @apps << app
    end
    Also aliased as: <<
    call(env) click to toggle source
    # File lib/rack/cascade.rb, line 19
    def call(env)
      result = NotFound
    
      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)
        last_body = result[2]
        break unless @catch.include?(result[0].to_i)
      end
    
      result
    end
    include?(app) click to toggle source
    # File lib/rack/cascade.rb, line 46
    def include?(app)
      @has_app.include? app
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!7MN:N:Rack/Lint.htmlnu[ Class: Rack::Lint

    In Files

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Lint

    Rack::Lint validates your application and the requests and responses according to the Rack spec.

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/lint.rb, line 9
    def initialize(app)
      @app = app
      @content_length = nil
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!u66Rack/Directory.htmlnu[ Class: Rack::Directory

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Directory

    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::File of the same root will be used.

    Constants

    DIR_FILE
    DIR_PAGE
    F
    FILESIZE_FORMAT

    Stolen from Ramaze

    Attributes

    files[R]
    path[RW]
    root[RW]

    Public Class Methods

    new(root, app=nil) click to toggle source
    # File lib/rack/directory.rb, line 45
    def initialize(root, app=nil)
      @root = F.expand_path(root)
      @app = app || Rack::File.new(@root)
    end

    Public Instance Methods

    _call(env) click to toggle source
    # File lib/rack/directory.rb, line 56
    def _call(env)
      @env = env
      @script_name = env[SCRIPT_NAME]
      @path_info = Utils.unescape(env[PATH_INFO])
    
      if forbidden = check_forbidden
        forbidden
      else
        @path = F.join(@root, @path_info)
        list_path
      end
    end
    call(env) click to toggle source
    # File lib/rack/directory.rb, line 50
    def call(env)
      dup._call(env)
    end
    check_forbidden() click to toggle source
    # File lib/rack/directory.rb, line 69
    def check_forbidden
      return unless @path_info.include? ".."
    
      body = "Forbidden\n"
      size = Rack::Utils.bytesize(body)
      return [403, {"Content-Type" => "text/plain",
        CONTENT_LENGTH => size.to_s,
        "X-Cascade" => "pass"}, [body]]
    end
    each() click to toggle source
    # File lib/rack/directory.rb, line 137
    def each
      show_path = Rack::Utils.escape_html(@path.sub(/^#{@root}/,''))
      files = @files.map{|f| DIR_FILE % DIR_FILE_escape(*f) }*"\n"
      page  = DIR_PAGE % [ show_path, show_path , files ]
      page.each_line{|l| yield l }
    end
    entity_not_found() click to toggle source
    # File lib/rack/directory.rb, line 129
    def entity_not_found
      body = "Entity not found: #{@path_info}\n"
      size = Rack::Utils.bytesize(body)
      return [404, {"Content-Type" => "text/plain",
        CONTENT_LENGTH => size.to_s,
        "X-Cascade" => "pass"}, [body]]
    end
    filesize_format(int) click to toggle source
    # File lib/rack/directory.rb, line 153
    def filesize_format(int)
      FILESIZE_FORMAT.each do |format, size|
        return format % (int.to_f / size) if int >= size
      end
    
      int.to_s + 'B'
    end
    list_directory() click to toggle source
    # File lib/rack/directory.rb, line 79
    def list_directory
      @files = [['../','Parent Directory','','','']]
      glob = F.join(@path, '*')
    
      url_head = (@script_name.split('/') + @path_info.split('/')).map do |part|
        Rack::Utils.escape part
      end
    
      Dir[glob].sort.each do |node|
        stat = stat(node)
        next  unless stat
        basename = F.basename(node)
        ext = F.extname(node)
    
        url = F.join(*url_head + [Rack::Utils.escape(basename)])
        size = stat.size
        type = stat.directory? ? 'directory' : Mime.mime_type(ext)
        size = stat.directory? ? '-' : filesize_format(size)
        mtime = stat.mtime.httpdate
        url << '/'  if stat.directory?
        basename << '/'  if stat.directory?
    
        @files << [ url, basename, size, type, mtime ]
      end
    
      return [ 200, { CONTENT_TYPE =>'text/html; charset=utf-8'}, self ]
    end
    list_path() click to toggle source

    TODO: add correct response if not readable, not sure if 404 is the best

    option
    # File lib/rack/directory.rb, line 115
    def list_path
      @stat = F.stat(@path)
    
      if @stat.readable?
        return @app.call(@env) if @stat.file?
        return list_directory if @stat.directory?
      else
        raise Errno::ENOENT, 'No such file or directory'
      end
    
    rescue Errno::ENOENT, Errno::ELOOP
      return entity_not_found
    end
    stat(node, max = 10) click to toggle source
    # File lib/rack/directory.rb, line 107
    def stat(node, max = 10)
      F.stat(node)
    rescue Errno::ENOENT, Errno::ELOOP
      return nil
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK! r99"Rack/RewindableInput/Tempfile.htmlnu[ Class: Rack::RewindableInput::Tempfile

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::RewindableInput::Tempfile

    Ruby's Tempfile class has a bug. Subclass it and fix it.

    Public Instance Methods

    _close() click to toggle source
    # File lib/rack/rewindable_input.rb, line 61
    def _close
      @tmpfile.close if @tmpfile
      @data[1] = nil if @data
      @tmpfile = nil
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!4<<Rack/Auth/AbstractHandler.htmlnu[ Class: Rack::Auth::AbstractHandler

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth::AbstractHandler

    Rack::Auth::AbstractHandler implements common authentication functionality.

    realm should be set for all handlers.

    Attributes

    realm[RW]

    Public Class Methods

    new(app, realm=nil, &authenticator) click to toggle source
    # File lib/rack/auth/abstract/handler.rb, line 11
    def initialize(app, realm=nil, &authenticator)
      @app, @realm, @authenticator = app, realm, authenticator
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!0 C CRack/Auth/Basic/Request.htmlnu[ Class: Rack::Auth::Basic::Request

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth::Basic::Request

    Public Instance Methods

    basic?() click to toggle source
    # File lib/rack/auth/basic.rb, line 43
    def basic?
      "basic" == scheme
    end
    credentials() click to toggle source
    # File lib/rack/auth/basic.rb, line 47
    def credentials
      @credentials ||= params.unpack("m*").first.split(/:/, 2)
    end
    username() click to toggle source
    # File lib/rack/auth/basic.rb, line 51
    def username
      credentials.first
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!lPDQDQRack/Auth/AbstractRequest.htmlnu[ Class: Rack::Auth::AbstractRequest

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth::AbstractRequest

    Constants

    AUTHORIZATION_KEYS

    Public Class Methods

    new(env) click to toggle source
    # File lib/rack/auth/abstract/request.rb, line 7
    def initialize(env)
      @env = env
    end

    Public Instance Methods

    params() click to toggle source
    # File lib/rack/auth/abstract/request.rb, line 27
    def params
      @params ||= parts.last
    end
    parts() click to toggle source
    # File lib/rack/auth/abstract/request.rb, line 19
    def parts
      @parts ||= @env[authorization_key].split(' ', 2)
    end
    provided?() click to toggle source
    # File lib/rack/auth/abstract/request.rb, line 15
    def provided?
      !authorization_key.nil?
    end
    request() click to toggle source
    # File lib/rack/auth/abstract/request.rb, line 11
    def request
      @request ||= Request.new(@env)
    end
    scheme() click to toggle source
    # File lib/rack/auth/abstract/request.rb, line 23
    def scheme
      @scheme ||= parts.first && parts.first.downcase
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!s%=77Rack/Auth/Digest.htmlnu[ Module: Rack::Auth::Digest

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth::Digest

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!ģ M?M?Rack/Auth/Basic.htmlnu[ Class: Rack::Auth::Basic

    Parent

    Namespace

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth::Basic

    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.

    See also: example/protectedlobster.rb

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/auth/basic.rb, line 15
    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

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!OQg_g_Rack/Auth/Digest/Nonce.htmlnu[ Class: Rack::Auth::Digest::Nonce

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth::Digest::Nonce

    Rack::Auth::Digest::Nonce is the default nonce generator for the Rack::Auth::Digest::MD5 authentication handler.

    private_key needs to set to a constant string.

    time_limit can be optionally set to an integer (number of seconds), to limit the validity of the generated nonces.

    Attributes

    private_key[RW]
    time_limit[RW]

    Public Class Methods

    new(timestamp = Time.now, given_digest = nil) click to toggle source
    # File lib/rack/auth/digest/nonce.rb, line 24
    def initialize(timestamp = Time.now, given_digest = nil)
      @timestamp, @given_digest = timestamp.to_i, given_digest
    end
    parse(string) click to toggle source
    # File lib/rack/auth/digest/nonce.rb, line 20
    def self.parse(string)
      new(*string.unpack("m*").first.split(' ', 2))
    end

    Public Instance Methods

    digest() click to toggle source
    # File lib/rack/auth/digest/nonce.rb, line 32
    def digest
      ::Digest::MD5.hexdigest([ @timestamp, self.class.private_key ] * ':')
    end
    fresh?() click to toggle source
    # File lib/rack/auth/digest/nonce.rb, line 44
    def fresh?
      !stale?
    end
    stale?() click to toggle source
    # File lib/rack/auth/digest/nonce.rb, line 40
    def stale?
      !self.class.time_limit.nil? && (Time.now.to_i - @timestamp) > self.class.time_limit
    end
    to_s() click to toggle source
    # File lib/rack/auth/digest/nonce.rb, line 28
    def to_s
      [([ @timestamp, digest ] * ' ')].pack("m*").strip
    end
    valid?() click to toggle source
    # File lib/rack/auth/digest/nonce.rb, line 36
    def valid?
      digest == @given_digest
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!:l/ddRack/Auth/Digest/Params.htmlnu[ Class: Rack::Auth::Digest::Params

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth::Digest::Params

    Constants

    UNQUOTED

    Public Class Methods

    dequote(str) click to toggle source
    # File lib/rack/auth/digest/params.rb, line 13
    def self.dequote(str) # From WEBrick::HTTPUtils
      ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
      ret.gsub!(/\\(.)/, "\\1")
      ret
    end
    new() click to toggle source
    # File lib/rack/auth/digest/params.rb, line 23
    def initialize
      super()
    
      yield self if block_given?
    end
    parse(str) click to toggle source
    # File lib/rack/auth/digest/params.rb, line 6
    def self.parse(str)
      Params[*split_header_value(str).map do |param|
        k, v = param.split('=', 2)
        [k, dequote(v)]
      end.flatten]
    end
    split_header_value(str) click to toggle source
    # File lib/rack/auth/digest/params.rb, line 19
    def self.split_header_value(str)
      str.scan( /(\w+\=(?:"[^\"]+"|[^,]+))/ ).collect{ |v| v[0] }
    end

    Public Instance Methods

    [](k) click to toggle source
    # File lib/rack/auth/digest/params.rb, line 29
    def [](k)
      super k.to_s
    end
    []=(k, v) click to toggle source
    # File lib/rack/auth/digest/params.rb, line 33
    def []=(k, v)
      super k.to_s, v.to_s
    end
    quote(str) click to toggle source
    # File lib/rack/auth/digest/params.rb, line 45
    def quote(str) # From WEBrick::HTTPUtils
      '"' << str.gsub(/[\\\"]/, "\\\11"") << '"'
    end
    to_s() click to toggle source
    # File lib/rack/auth/digest/params.rb, line 39
    def to_s
      map do |k, v|
        "#{k}=" + (UNQUOTED.include?(k) ? v.to_s : quote(v))
      end.join(', ')
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!m)=XXRack/Auth/Digest/Request.htmlnu[ Class: Rack::Auth::Digest::Request

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth::Digest::Request

    Public Instance Methods

    correct_uri?() click to toggle source
    # File lib/rack/auth/digest/request.rb, line 17
    def correct_uri?
      request.fullpath == uri
    end
    digest?() click to toggle source
    # File lib/rack/auth/digest/request.rb, line 13
    def digest?
      "digest" == scheme
    end
    method() click to toggle source
    # File lib/rack/auth/digest/request.rb, line 9
    def method
      @env['rack.methodoverride.original_method'] || @env[REQUEST_METHOD]
    end
    method_missing(sym, *args) click to toggle source
    # File lib/rack/auth/digest/request.rb, line 33
    def method_missing(sym, *args)
      return super unless params.has_key?(key = sym.to_s)
      return params[key] if args.size == 0
      raise ArgumentError, "wrong number of arguments (#{args.size} for 0)"
    end
    nonce() click to toggle source
    # File lib/rack/auth/digest/request.rb, line 21
    def nonce
      @nonce ||= Nonce.parse(params['nonce'])
    end
    params() click to toggle source
    # File lib/rack/auth/digest/request.rb, line 25
    def params
      @params ||= Params.parse(parts.last)
    end
    respond_to?(sym, *) click to toggle source
    # File lib/rack/auth/digest/request.rb, line 29
    def respond_to?(sym, *)
      super or params.has_key? sym.to_s
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!MN(W(WRack/Auth/Digest/MD5.htmlnu[ Class: Rack::Auth::Digest::MD5

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Auth::Digest::MD5

    Rack::Auth::Digest::MD5 implements the MD5 algorithm version of HTTP Digest Authentication, as per RFC 2617.

    Initialize with the [Rack] application that you want protecting, and a block that looks up a plaintext password for a given username.

    opaque needs to be set to a constant base64/hexadecimal string.

    Constants

    QOP

    Attributes

    opaque[RW]
    passwords_hashed[W]

    Public Class Methods

    new(app, realm=nil, opaque=nil, &authenticator) click to toggle source
    # File lib/rack/auth/digest/md5.rb, line 24
    def initialize(app, realm=nil, opaque=nil, &authenticator)
      @passwords_hashed = nil
      if opaque.nil? and realm.respond_to? :values_at
        realm, opaque, @passwords_hashed = realm.values_at :realm, :opaque, :passwords_hashed
      end
      super(app, realm, &authenticator)
      @opaque = opaque
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/auth/digest/md5.rb, line 37
    def call(env)
      auth = Request.new(env)
    
      unless auth.provided?
        return unauthorized
      end
    
      if !auth.digest? || !auth.correct_uri? || !valid_qop?(auth)
        return bad_request
      end
    
      if valid?(auth)
        if auth.nonce.stale?
          return unauthorized(challenge(:stale => true))
        else
          env['REMOTE_USER'] = auth.username
    
          return @app.call(env)
        end
      end
    
      unauthorized
    end
    passwords_hashed?() click to toggle source
    # File lib/rack/auth/digest/md5.rb, line 33
    def passwords_hashed?
      !!@passwords_hashed
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!c2c2Rack/Lint/ErrorWrapper.htmlnu[ Class: Rack::Lint::ErrorWrapper

    In Files

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Lint::ErrorWrapper

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!g=e2e2Rack/Lint/HijackWrapper.htmlnu[ Class: Rack::Lint::HijackWrapper

    In Files

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Lint::HijackWrapper

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!6`wC2C2Rack/Lint/LintError.htmlnu[ Class: Rack::Lint::LintError

    In Files

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Lint::LintError

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!c2c2Rack/Lint/InputWrapper.htmlnu[ Class: Rack::Lint::InputWrapper

    In Files

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Lint::InputWrapper

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!TTRack/BodyProxy.htmlnu[ Class: Rack::BodyProxy

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::BodyProxy

    Public Class Methods

    new(body, &block) click to toggle source
    # File lib/rack/body_proxy.rb, line 3
    def initialize(body, &block)
      @body, @block, @closed = body, block, false
    end

    Public Instance Methods

    close() click to toggle source
    # File lib/rack/body_proxy.rb, line 12
    def close
      return if @closed
      @closed = true
      begin
        @body.close if @body.respond_to? :close
      ensure
        @block.call
      end
    end
    closed?() click to toggle source
    # File lib/rack/body_proxy.rb, line 22
    def closed?
      @closed
    end
    each(*args, &block) click to toggle source

    N.B. This method is a special case to address the bug described by #434. We are applying this special case for each only. Future bugs of this class will be handled by requesting users to patch their ruby implementation, to save adding too many methods in this class.

    # File lib/rack/body_proxy.rb, line 30
    def each(*args, &block)
      @body.each(*args, &block)
    end
    method_missing(*args, &block) click to toggle source
    # File lib/rack/body_proxy.rb, line 34
    def method_missing(*args, &block)
      super if args.first.to_s =~ /^to_ary$/
      @body.__send__(*args, &block)
    end
    respond_to?(*args) click to toggle source
    # File lib/rack/body_proxy.rb, line 7
    def respond_to?(*args)
      return false if args.first.to_s =~ /^to_ary$/
      super or @body.respond_to?(*args)
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!(3fGG Rack/Deflater/DeflateStream.htmlnu[ Class: Rack::Deflater::DeflateStream

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Deflater::DeflateStream

    Constants

    DEFLATE_ARGS

    Public Class Methods

    new(body) click to toggle source
    # File lib/rack/deflater.rb, line 113
    def initialize(body)
      @body = body
      @closed = false
    end

    Public Instance Methods

    close() click to toggle source
    # File lib/rack/deflater.rb, line 127
    def close
      return if @closed
      @closed = true
      @body.close if @body.respond_to?(:close)
    end
    each() click to toggle source
    # File lib/rack/deflater.rb, line 118
    def each
      deflator = ::Zlib::Deflate.new(*DEFLATE_ARGS)
      @body.each { |part| yield deflator.deflate(part, Zlib::SYNC_FLUSH) }
      yield deflator.finish
      nil
    ensure
      deflator.close
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!e%KKRack/Deflater/GzipStream.htmlnu[ Class: Rack::Deflater::GzipStream

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Deflater::GzipStream

    Public Class Methods

    new(body, mtime) click to toggle source
    # File lib/rack/deflater.rb, line 74
    def initialize(body, mtime)
      @body = body
      @mtime = mtime
      @closed = false
    end

    Public Instance Methods

    close() click to toggle source
    # File lib/rack/deflater.rb, line 97
    def close
      return if @closed
      @closed = true
      @body.close if @body.respond_to?(:close)
    end
    each(&block) click to toggle source
    # File lib/rack/deflater.rb, line 80
    def each(&block)
      @writer = block
      gzip  =::Zlib::GzipWriter.new(self)
      gzip.mtime = @mtime
      @body.each { |part|
        gzip.write(part)
        gzip.flush
      }
    ensure
      gzip.close
      @writer = nil
    end
    write(data) click to toggle source
    # File lib/rack/deflater.rb, line 93
    def write(data)
      @writer.call(data)
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!aXATFTFRack/CommonLogger.htmlnu[ Class: Rack::CommonLogger

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::CommonLogger

    Rack::CommonLogger forwards every request to the given app, and logs a line in the Apache common log format 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)

    Constants

    FORMAT

    Common Log Format: 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} %

    Public Class Methods

    new(app, logger=nil) click to toggle source
    # File lib/rack/commonlogger.rb, line 26
    def initialize(app, logger=nil)
      @app = app
      @logger = logger
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/commonlogger.rb, line 31
    def call(env)
      began_at = Time.now
      status, header, body = @app.call(env)
      header = Utils::HeaderHash.new(header)
      body = BodyProxy.new(body) { log(env, status, header, began_at) }
      [status, header, body]
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!9BBRack/Lock.htmlnu[ Class: Rack::Lock

    In Files

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Lock

    Rack::Lock locks every request inside a mutex, so that every request will effectively be executed synchronously.

    Constants

    FLAG

    Public Class Methods

    new(app, mutex = Mutex.new) click to toggle source
    # File lib/rack/lock.rb, line 10
    def initialize(app, mutex = Mutex.new)
      @app, @mutex = app, mutex
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/lock.rb, line 14
    def call(env)
      old, env[FLAG] = env[FLAG], false
      @mutex.lock
      response = @app.call(env)
      body = BodyProxy.new(response[2]) { @mutex.unlock }
      response[2] = body
      response
    ensure
      @mutex.unlock unless body
      env[FLAG] = old
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!ISSRack/Reloader/Stat.htmlnu[ Module: Rack::Reloader::Stat

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Reloader::Stat

    Public Instance Methods

    figure_path(file, paths) click to toggle source

    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.

    # File lib/rack/reloader.rb, line 85
    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
    rotation() click to toggle source
    # File lib/rack/reloader.rb, line 66
    def rotation
      files = [$0, *$LOADED_FEATURES].uniq
      paths = ['./', *$LOAD_PATH].uniq
    
      files.map{|file|
        next if file =~ /\.(so|bundle)$/ # 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
    safe_stat(file) click to toggle source
    # File lib/rack/reloader.rb, line 100
    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

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!n:~:~Rack/Builder.htmlnu[ Class: Rack::Builder

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Builder

    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.

    Public Class Methods

    app(default_app = nil, &block) click to toggle source
    # File lib/rack/builder.rb, line 58
    def self.app(default_app = nil, &block)
      self.new(default_app, &block).to_app
    end
    new(default_app = nil,&block) click to toggle source
    # File lib/rack/builder.rb, line 53
    def initialize(default_app = nil,&block)
      @use, @map, @run, @warmup = [], nil, default_app, nil
      instance_eval(&block) if block_given?
    end
    new_from_string(builder_script, file="(rackup)") click to toggle source
    # File lib/rack/builder.rb, line 48
    def self.new_from_string(builder_script, file="(rackup)")
      eval "Rack::Builder.new {\n" + builder_script + "\n}.to_app",
        TOPLEVEL_BINDING, file, 0
    end
    parse_file(config, opts = Server::Options.new) click to toggle source
    # File lib/rack/builder.rb, line 32
    def self.parse_file(config, opts = Server::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/, '')
        app = new_from_string cfgfile, config
      else
        require config
        app = Object.const_get(::File.basename(config, '.rb').capitalize)
      end
      return app, options
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/builder.rb, line 152
    def call(env)
      to_app.call(env)
    end
    map(path, &block) click to toggle source

    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.

    # File lib/rack/builder.rb, line 139
    def map(path, &block)
      @map ||= {}
      @map[path] = block
    end
    run(app) click to toggle source

    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
    # File lib/rack/builder.rb, line 103
    def run(app)
      @run = app
    end
    to_app() click to toggle source
    # File lib/rack/builder.rb, line 144
    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) if @warmup
      app
    end
    use(middleware, *args, &block) click to toggle source

    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.

    # File lib/rack/builder.rb, line 81
    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
    warmup(prc=nil, &block) click to toggle source

    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
    # File lib/rack/builder.rb, line 116
    def warmup(prc=nil, &block)
      @warmup = prc || block
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!I8o8oRack/Handler.htmlnu[ Module: Rack::Handler

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Handler

    Handlers connect web servers with Rack.

    Rack includes Handlers for Thin, WEBrick, FastCGI, CGI, SCGI and LiteSpeed.

    Handlers usually are activated by calling MyHandler.run(myapp). A second optional hash can be passed to include server-specific configuration.

    Public Class Methods

    default(options = {}) click to toggle source
    # File lib/rack/handler.rb, line 46
    def self.default(options = {})
      # Guess.
      if ENV.include?("PHP_FCGI_CHILDREN")
        # We already speak FastCGI
        options.delete :File
        options.delete :Port
    
        Rack::Handler::FastCGI
      elsif ENV.include?(REQUEST_METHOD)
        Rack::Handler::CGI
      elsif ENV.include?("RACK_HANDLER")
        self.get(ENV["RACK_HANDLER"])
      else
        pick ['thin', 'puma', 'webrick']
      end
    end
    get(server) click to toggle source
    # File lib/rack/handler.rb, line 11
    def self.get(server)
      return unless server
      server = server.to_s
    
      unless @handlers.include? server
        load_error = try_require('rack/handler', server)
      end
    
      if klass = @handlers[server]
        klass.split("::").inject(Object) { |o, x| o.const_get(x) }
      else
        const_get(server, false)
      end
    
    rescue NameError => name_error
      raise load_error || name_error
    end
    pick(server_names) click to toggle source

    Select first available Rack handler given an `Array` of server names. Raises `LoadError` if no handler was found.

    > pick ['thin', 'webrick']
    => Rack::Handler::WEBrick
    # File lib/rack/handler.rb, line 34
    def self.pick(server_names)
      server_names = Array(server_names)
      server_names.each do |server_name|
        begin
          return get(server_name.to_s)
        rescue LoadError, NameError
        end
      end
    
      raise LoadError, "Couldn't find handler for: #{server_names.join(', ')}."
    end
    register(server, klass) click to toggle source
    # File lib/rack/handler.rb, line 84
    def self.register(server, klass)
      @handlers ||= {}
      @handlers[server.to_s] = klass.to_s
    end
    try_require(prefix, const_name) click to toggle source

    Transforms server-name constants to their canonical form as filenames, then tries to require them but silences the LoadError if not found

    Naming convention:

    Foo # => 'foo'
    FooBar # => 'foo_bar.rb'
    FooBAR # => 'foobar.rb'
    FOObar # => 'foobar.rb'
    FOOBAR # => 'foobar.rb'
    FooBarBaz # => 'foo_bar_baz.rb'
    # File lib/rack/handler.rb, line 74
    def self.try_require(prefix, const_name)
      file = const_name.gsub(/^[A-Z]+/) { |pre| pre.downcase }.
        gsub(/[A-Z]+[^A-Z]/, '_\&').downcase
    
      require(::File.join(prefix, file))
      nil
    rescue LoadError => error
      error
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!vIUIURack/Reloader.htmlnu[ Class: Rack::Reloader

    Parent

    Namespace

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Reloader

    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.

    Public Class Methods

    new(app, cooldown = 10, backend = Stat) click to toggle source
    # File lib/rack/reloader.rb, line 23
    def initialize(app, cooldown = 10, backend = Stat)
      @app = app
      @cooldown = cooldown
      @last = (Time.now - cooldown)
      @cache = {}
      @mtimes = {}
    
      extend backend
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/reloader.rb, line 33
    def call(env)
      if @cooldown and Time.now > @last + @cooldown
        if Thread.list.size > 1
          Thread.exclusive{ reload! }
        else
          reload!
        end
    
        @last = Time.now
      end
    
      @app.call(env)
    end
    reload!(stderr = $stderr) click to toggle source
    # File lib/rack/reloader.rb, line 47
    def reload!(stderr = $stderr)
      rotation do |file, mtime|
        previous_mtime = @mtimes[file] ||= mtime
        safe_load(file, mtime, stderr) if mtime > previous_mtime
      end
    end
    safe_load(file, mtime, stderr = $stderr) click to toggle source

    A safe Kernel::load, issuing the hooks depending on the results

    # File lib/rack/reloader.rb, line 55
    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

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!Rack/Server.htmlnu[ Class: Rack::Server

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Server

    Attributes

    options[W]

    Public Class Methods

    default_middleware_by_environment() click to toggle source
    # File lib/rack/server.rb, line 218
    def default_middleware_by_environment
      m = Hash.new {|h,k| h[k] = []}
      m["deployment"] = [
        [Rack::ContentLength],
        [Rack::Chunked],
        logging_middleware,
        [Rack::TempfileReaper]
      ]
      m["development"] = [
        [Rack::ContentLength],
        [Rack::Chunked],
        logging_middleware,
        [Rack::ShowExceptions],
        [Rack::Lint],
        [Rack::TempfileReaper]
      ]
    
      m
    end
    logging_middleware() click to toggle source
    # File lib/rack/server.rb, line 212
    def logging_middleware
      lambda { |server|
        server.server.name =~ /CGI/ || server.options[:quiet] ? nil : [Rack::CommonLogger, $stderr]
      }
    end
    middleware() click to toggle source
    # File lib/rack/server.rb, line 238
    def middleware
      default_middleware_by_environment
    end
    new(options = nil) click to toggle source

    Options may include:

    • :app

      a rack application to run (overrides :config)
    • :config

      a rackup configuration file path to load (.ru)
    • :environment

      this selects the middleware that will be wrapped around
      your application. Default options available are:
        - development: CommonLogger, ShowExceptions, and Lint
        - deployment: CommonLogger
        - none: no extra middleware
      note: when the server is a cgi server, CommonLogger is not included.
    • :server

      choose a specific Rack::Handler, e.g. cgi, fcgi, webrick
    • :daemonize

      if true, the server will daemonize itself (fork, detach, etc)
    • :pid

      path to write a pid file after daemonize
    • :Host

      the host address to bind to (used by supporting Rack::Handler)
    • :Port

      the port to bind to (used by supporting Rack::Handler)
    • :AccessLog

      webrick access log options (or supporting Rack::Handler)
    • :debug

      turn on debug output ($DEBUG = true)
    • :warn

      turn on warnings ($-w = true)
    • :include

      add given paths to $LOAD_PATH
    • :require

      require the given libraries
    # File lib/rack/server.rb, line 184
    def initialize(options = nil)
      @options = options
      @app = options[:app] if options && options[:app]
    end
    start(options = nil) click to toggle source

    Start a new rack server (like running rackup). This will parse ARGV and provide standard ARGV rackup options, defaulting to load 'config.ru'.

    Providing an options hash will prevent ARGV parsing and will not include any default options.

    This method can be used to very easily launch a CGI application, for example:

    Rack::Server.start(
      :app => lambda do |e|
        [200, {'Content-Type' => 'text/html'}, ['hello world']]
      end,
      :server => 'cgi'
    )

    Further options available here are documented on Rack::Server#initialize

    # File lib/rack/server.rb, line 146
    def self.start(options = nil)
      new(options).start
    end

    Public Instance Methods

    app() click to toggle source
    # File lib/rack/server.rb, line 207
    def app
      @app ||= options[:builder] ? build_app_from_string : build_app_and_options_from_config
    end
    default_options() click to toggle source
    # File lib/rack/server.rb, line 193
    def default_options
      environment  = ENV['RACK_ENV'] || 'development'
      default_host = environment == 'development' ? 'localhost' : '0.0.0.0'
    
      {
        :environment => environment,
        :pid         => nil,
        :Port        => 9292,
        :Host        => default_host,
        :AccessLog   => [],
        :config      => "config.ru"
      }
    end
    middleware() click to toggle source
    # File lib/rack/server.rb, line 243
    def middleware
      self.class.middleware
    end
    options() click to toggle source
    # File lib/rack/server.rb, line 189
    def options
      @options ||= parse_options(ARGV)
    end
    server() click to toggle source
    # File lib/rack/server.rb, line 289
    def server
      @_server ||= Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
    end
    start(&blk) click to toggle source
    # File lib/rack/server.rb, line 247
    def start &blk
      if options[:warn]
        $-w = true
      end
    
      if includes = options[:include]
        $LOAD_PATH.unshift(*includes)
      end
    
      if library = options[:require]
        require library
      end
    
      if options[:debug]
        $DEBUG = true
        require 'pp'
        p options[:server]
        pp wrapped_app
        pp app
      end
    
      check_pid! if options[:pid]
    
      # Touch the wrapped app, so that the config.ru is loaded before
      # daemonization (i.e. before chdir, etc).
      wrapped_app
    
      daemonize_app if options[:daemonize]
    
      write_pid if options[:pid]
    
      trap(:INT) do
        if server.respond_to?(:shutdown)
          server.shutdown
        else
          exit
        end
      end
    
      server.run wrapped_app, options, &blk
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!v |H|HRack/ConditionalGet.htmlnu[ Class: Rack::ConditionalGet

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::ConditionalGet

    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: github.com/wycats/merb/blob/master/merb-core/lib/merb-core/rack/middleware/conditional_get.rb

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/conditionalget.rb, line 18
    def initialize(app)
      @app = app
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/conditionalget.rb, line 22
    def call(env)
      case env[REQUEST_METHOD]
      when "GET", "HEAD"
        status, headers, body = @app.call(env)
        headers = Utils::HeaderHash.new(headers)
        if status == 200 && fresh?(env, headers)
          status = 304
          headers.delete(CONTENT_TYPE)
          headers.delete(CONTENT_LENGTH)
          original_body = body
          body = Rack::BodyProxy.new([]) do
            original_body.close if original_body.respond_to?(:close)
          end
        end
        [status, headers, body]
      else
        @app.call(env)
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!XአnnRack/Session/Memcache.htmlnu[ Class: Rack::Session::Memcache

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Memcache

    Rack::Session::Memcache provides simple cookie based session management. Session data is stored in memcached. The corresponding session key is maintained in the cookie. You may treat Session::Memcache as you would Session::Pool with the following caveats.

    • Setting :expire_after to 0 would note to the Memcache server to hang onto the session data until it would drop it according to it's own specifications. However, the cookie sent to the client would expire immediately.

    Note that memcache does drop data before it may be listed to expire. For a full description of behaviour, please see memcache's documentation.

    Constants

    DEFAULT_OPTIONS

    Attributes

    mutex[R]
    pool[R]

    Public Class Methods

    new(app, options={}) click to toggle source
    # File lib/rack/session/memcache.rb, line 29
    def initialize(app, options={})
      super
    
      @mutex = Mutex.new
      mserv = @default_options[:memcache_server]
      mopts = @default_options.reject{|k,v| !MemCache::DEFAULT_OPTIONS.include? k }
    
      @pool = options[:cache] || MemCache.new(mserv, mopts)
      unless @pool.active? and @pool.servers.any?{|c| c.alive? }
        raise 'No memcache servers'
      end
    end

    Public Instance Methods

    destroy_session(env, session_id, options) click to toggle source
    # File lib/rack/session/memcache.rb, line 71
    def destroy_session(env, session_id, options)
      with_lock(env) do
        @pool.delete(session_id)
        generate_sid unless options[:drop]
      end
    end
    generate_sid() click to toggle source
    # File lib/rack/session/memcache.rb, line 42
    def generate_sid
      loop do
        sid = super
        break sid unless @pool.get(sid, true)
      end
    end
    get_session(env, sid) click to toggle source
    # File lib/rack/session/memcache.rb, line 49
    def get_session(env, sid)
      with_lock(env) do
        unless sid and session = @pool.get(sid)
          sid, session = generate_sid, {}
          unless /^STORED/ =~ @pool.add(sid, session)
            raise "Session collision on '#{sid.inspect}'"
          end
        end
        [sid, session]
      end
    end
    set_session(env, session_id, new_session, options) click to toggle source
    # File lib/rack/session/memcache.rb, line 61
    def set_session(env, session_id, new_session, options)
      expiry = options[:expire_after]
      expiry = expiry.nil? ? 0 : expiry + 1
    
      with_lock(env) do
        @pool.set session_id, new_session, expiry
        session_id
      end
    end
    with_lock(env) click to toggle source
    # File lib/rack/session/memcache.rb, line 78
    def with_lock(env)
      @mutex.lock if env['rack.multithread']
      yield
    rescue MemCache::MemCacheError, Errno::ECONNREFUSED
      if $VERBOSE
        warn "#{self} is unable to find memcached server."
        warn $!.inspect
      end
      raise
    ensure
      @mutex.unlock if @mutex.locked?
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!*+IQaQaRack/Session/Pool.htmlnu[ Class: Rack::Session::Pool

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Pool

    Rack::Session::Pool provides simple cookie based session management. Session data is stored in a hash held by @pool. In the context of a multithreaded environment, sessions being committed to the pool is done in a merging manner.

    The :drop option is available in rack.session.options if you wish to explicitly remove the session from the session cache.

    Example:

    myapp = MyRackApp.new
    sessioned = Rack::Session::Pool.new(myapp,
      :domain => 'foo.com',
      :expire_after => 2592000
    )
    Rack::Handler::WEBrick.run sessioned

    Constants

    DEFAULT_OPTIONS

    Attributes

    mutex[R]
    pool[R]

    Public Class Methods

    new(app, options={}) click to toggle source
    # File lib/rack/session/pool.rb, line 31
    def initialize(app, options={})
      super
      @pool = Hash.new
      @mutex = Mutex.new
    end

    Public Instance Methods

    destroy_session(env, session_id, options) click to toggle source
    # File lib/rack/session/pool.rb, line 61
    def destroy_session(env, session_id, options)
      with_lock(env) do
        @pool.delete(session_id)
        generate_sid unless options[:drop]
      end
    end
    generate_sid() click to toggle source
    # File lib/rack/session/pool.rb, line 37
    def generate_sid
      loop do
        sid = super
        break sid unless @pool.key? sid
      end
    end
    get_session(env, sid) click to toggle source
    # File lib/rack/session/pool.rb, line 44
    def get_session(env, sid)
      with_lock(env) do
        unless sid and session = @pool[sid]
          sid, session = generate_sid, {}
          @pool.store sid, session
        end
        [sid, session]
      end
    end
    set_session(env, session_id, new_session, options) click to toggle source
    # File lib/rack/session/pool.rb, line 54
    def set_session(env, session_id, new_session, options)
      with_lock(env) do
        @pool.store session_id, new_session
        session_id
      end
    end
    with_lock(env) click to toggle source
    # File lib/rack/session/pool.rb, line 68
    def with_lock(env)
      @mutex.lock if env['rack.multithread']
      yield
    ensure
      @mutex.unlock if @mutex.locked?
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!B3V5V5Rack/Session/Abstract.htmlnu[ Module: Rack::Session::Abstract

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Abstract

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!#+FAFA'Rack/Session/Cookie/Base64/Marshal.htmlnu[ Class: Rack::Session::Cookie::Base64::Marshal

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Cookie::Base64::Marshal

    Encode session cookies as Marshaled Base64 data

    Public Instance Methods

    decode(str) click to toggle source
    # File lib/rack/session/cookie.rb, line 64
    def decode(str)
      return unless str
      ::Marshal.load(super(str)) rescue nil
    end
    encode(str) click to toggle source
    # File lib/rack/session/cookie.rb, line 60
    def encode(str)
      super(::Marshal.dump(str))
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!xvkBB$Rack/Session/Cookie/Base64/JSON.htmlnu[ Class: Rack::Session::Cookie::Base64::JSON

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Cookie::Base64::JSON

    N.B. Unlike other encoding methods, the contained objects must be a valid JSON composite type, either a Hash or an Array.

    Public Instance Methods

    decode(str) click to toggle source
    # File lib/rack/session/cookie.rb, line 77
    def decode(str)
      return unless str
      ::Rack::Utils::OkJson.decode(super(str)) rescue nil
    end
    encode(obj) click to toggle source
    # File lib/rack/session/cookie.rb, line 73
    def encode(obj)
      super(::Rack::Utils::OkJson.encode(obj))
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!qqCqC'Rack/Session/Cookie/Base64/ZipJSON.htmlnu[ Class: Rack::Session::Cookie::Base64::ZipJSON

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Cookie::Base64::ZipJSON

    Public Instance Methods

    decode(str) click to toggle source
    # File lib/rack/session/cookie.rb, line 88
    def decode(str)
      return unless str
      ::Rack::Utils::OkJson.decode(Zlib::Inflate.inflate(super(str)))
    rescue
      nil
    end
    encode(obj) click to toggle source
    # File lib/rack/session/cookie.rb, line 84
    def encode(obj)
      super(Zlib::Deflate.deflate(::Rack::Utils::OkJson.encode(obj)))
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!l:@@Rack/Session/Cookie/Base64.htmlnu[ Class: Rack::Session::Cookie::Base64

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Cookie::Base64

    Encode session cookies as Base64

    Public Instance Methods

    decode(str) click to toggle source
    # File lib/rack/session/cookie.rb, line 54
    def decode(str)
      str.unpack('m').first
    end
    encode(str) click to toggle source
    # File lib/rack/session/cookie.rb, line 50
    def encode(str)
      [str].pack('m')
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!?r==!Rack/Session/Cookie/Identity.htmlnu[ Class: Rack::Session::Cookie::Identity

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Cookie::Identity

    Use no encoding for session cookies

    Public Instance Methods

    decode(str) click to toggle source
    # File lib/rack/session/cookie.rb, line 100
    def decode(str); str; end
    encode(str) click to toggle source
    # File lib/rack/session/cookie.rb, line 99
    def encode(str); str; end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!W#yGyGRack/Session/Cookie.htmlnu[ Class: Rack::Session::Cookie

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Cookie

    Rack::Session::Cookie provides simple cookie based session management. By default, the session is a Ruby Hash stored as base64 encoded marshalled data set to :key (default: rack.session). The object that encodes the session data is configurable and must respond to encode and decode. Both methods must take a string and return a string.

    When the secret key is set, cookie data is checked for data integrity. The old secret key is also accepted and allows graceful secret rotation.

    Example:

    use Rack::Session::Cookie, :key => 'rack.session',
                               :domain => 'foo.com',
                               :path => '/',
                               :expire_after => 2592000,
                               :secret => 'change_me',
                               :old_secret => 'also_change_me'
    
    All parameters are optional.

    Example of a cookie with no encoding:

    Rack::Session::Cookie.new(application, {
      :coder => Rack::Session::Cookie::Identity.new
    })

    Example of a cookie with custom encoding:

    Rack::Session::Cookie.new(application, {
      :coder => Class.new {
        def encode(str); str.reverse; end
        def decode(str); str.reverse; end
      }.new
    })

    Attributes

    coder[R]

    Public Class Methods

    new(app, options={}) click to toggle source
    # File lib/rack/session/cookie.rb, line 105
    def initialize(app, options={})
      @secrets = options.values_at(:secret, :old_secret).compact
      warn         SECURITY WARNING: No secret option provided to Rack::Session::Cookie.        This poses a security threat. It is strongly recommended that you        provide a secret to prevent exploits that may be possible from crafted        cookies. This will not be supported in future versions of Rack, and        future versions will even invalidate your existing user cookies.        Called from: #{caller[0]}. unless @secrets.size >= 1
      @coder  = options[:coder] ||= Base64::Marshal.new
      super(app, options.merge!(:cookie_only => true))
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!ڙtPSPSRack/Session/Abstract/ID.htmlnu[ Class: Rack::Session::Abstract::ID

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Abstract::ID

    ID sets up a basic framework for implementing an id based sessioning service. Cookies sent to the client for maintaining sessions will only contain an id reference. Only get_session and set_session are required to be overwritten.

    All parameters are optional.

    • :key determines the name of the cookie, by default it is 'rack.session'

    • :path, :domain, :expire_after, :secure, and :httponly set the related cookie options as by Rack::Response#add_cookie

    • :skip will not a set a cookie in the response nor update the session state

    • :defer will not set a cookie in the response but still update the session state if it is used with a backend

    • :renew (implementation dependent) will prompt the generation of a new session id, and migration of data to be referenced at the new id. If :defer is set, it will be overridden and the cookie will be set.

    • :sidbits sets the number of bits in length that a generated session id will be.

    These options can be set on a per request basis, at the location of env. Additionally the id of the session can be found within the options hash at the key :id. It is highly not recommended to change its value.

    Is Rack::Utils::Context compatible.

    Not included by default; you must require 'rack/session/abstract/id' to use.

    Constants

    DEFAULT_OPTIONS

    Attributes

    default_options[R]
    key[R]

    Public Class Methods

    new(app, options={}) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 211
    def initialize(app, options={})
      @app = app
      @default_options = self.class::DEFAULT_OPTIONS.merge(options)
      @key = @default_options.delete(:key)
      @cookie_only = @default_options.delete(:cookie_only)
      initialize_sid
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 219
    def call(env)
      context(env)
    end
    context(env, app=@app) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 223
    def context(env, app=@app)
      prepare_session(env)
      status, headers, body = app.call(env)
      commit_session(env, status, headers, body)
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!Ȗ&Rack/Session/Abstract/SessionHash.htmlnu[ Class: Rack::Session::Abstract::SessionHash

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Session::Abstract::SessionHash

    SessionHash is responsible to lazily load the session from store.

    Attributes

    id[W]

    Public Class Methods

    find(env) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 27
    def self.find(env)
      env[ENV_SESSION_KEY]
    end
    new(store, env) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 39
    def initialize(store, env)
      @store = store
      @env = env
      @loaded = false
    end
    set(env, session) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 31
    def self.set(env, session)
      env[ENV_SESSION_KEY] = session
    end
    set_options(env, options) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 35
    def self.set_options(env, options)
      env[ENV_SESSION_OPTIONS_KEY] = options.dup
    end

    Public Instance Methods

    [](key) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 59
    def [](key)
      load_for_read!
      @data[key.to_s]
    end
    Also aliased as: fetch
    []=(key, value) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 72
    def []=(key, value)
      load_for_write!
      @data[key.to_s] = value
    end
    Also aliased as: store
    clear() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 78
    def clear
      load_for_write!
      @data.clear
    end
    delete(key) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 104
    def delete(key)
      load_for_write!
      @data.delete(key.to_s)
    end
    destroy() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 83
    def destroy
      clear
      @id = @store.send(:destroy_session, @env, id, options)
    end
    each(&block) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 54
    def each(&block)
      load_for_read!
      @data.each(&block)
    end
    empty?() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 127
    def empty?
      load_for_read!
      @data.empty?
    end
    exists?() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 117
    def exists?
      return @exists if instance_variable_defined?(:@exists)
      @data = {}
      @exists = @store.send(:session_exists?, @env)
    end
    fetch(key) click to toggle source
    Alias for: []
    has_key?(key) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 65
    def has_key?(key)
      load_for_read!
      @data.has_key?(key.to_s)
    end
    Also aliased as: key?, include?
    id() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 45
    def id
      return @id if @loaded or instance_variable_defined?(:@id)
      @id = @store.send(:extract_session_id, @env)
    end
    include?(key) click to toggle source
    Alias for: has_key?
    inspect() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 109
    def inspect
      if loaded?
        @data.inspect
      else
        "#<#{self.class}:0x#{self.object_id.to_s(16)} not yet loaded>"
      end
    end
    key?(key) click to toggle source
    Alias for: has_key?
    keys() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 132
    def keys
      @data.keys
    end
    loaded?() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 123
    def loaded?
      @loaded
    end
    merge!(hash) click to toggle source
    Alias for: update
    options() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 50
    def options
      @env[ENV_SESSION_OPTIONS_KEY]
    end
    replace(hash) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 99
    def replace(hash)
      load_for_write!
      @data.replace(stringify_keys(hash))
    end
    store(key, value) click to toggle source
    Alias for: []=
    to_hash() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 88
    def to_hash
      load_for_read!
      @data.dup
    end
    update(hash) click to toggle source
    # File lib/rack/session/abstract/id.rb, line 93
    def update(hash)
      load_for_write!
      @data.update(stringify_keys(hash))
    end
    Also aliased as: merge!
    values() click to toggle source
    # File lib/rack/session/abstract/id.rb, line 136
    def values
      @data.values
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!eRack/Request.htmlnu[ Class: Rack::Request

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Request

    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"]

    Constants

    DEFAULT_PORTS

    Default ports depending on scheme. Used to decide whether or not to include the port in a generated URI.

    FORM_DATA_MEDIA_TYPES

    The set of form-data media-types. Requests that do not indicate one of the media types presents in this list will not be eligible for form-data / param parsing.

    PARSEABLE_DATA_MEDIA_TYPES

    The set of media-types. Requests that do not indicate one of the media types presents in this list will not be eligible for param parsing like soap attachments or generic multiparts

    Attributes

    env[R]

    The environment of the request.

    Public Class Methods

    new(env) click to toggle source
    # File lib/rack/request.rb, line 16
    def initialize(env)
      @env = env
    end

    Public Instance Methods

    GET() click to toggle source

    Returns the data received in the query string.

    # File lib/rack/request.rb, line 187
    def GET
      if @env["rack.request.query_string"] == query_string
        @env["rack.request.query_hash"]
      else
        p = parse_query({ :query => query_string, :separator => '&;' })
        @env["rack.request.query_string"] = query_string
        @env["rack.request.query_hash"]   = p
      end
    end
    POST() click to toggle source

    Returns the data received in the request body.

    This method support both application/x-www-form-urlencoded and multipart/form-data.

    # File lib/rack/request.rb, line 201
        def POST
          if @env["rack.input"].nil?
            raise "Missing rack.input"
          elsif @env["rack.request.form_input"].equal? @env["rack.input"]
            @env["rack.request.form_hash"]
          elsif form_data? || parseable_data?
            unless @env["rack.request.form_hash"] = parse_multipart(env)
              form_vars = @env["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[-1] == \00
    \
    
              @env["rack.request.form_vars"] = form_vars
              @env["rack.request.form_hash"] = parse_query({ :query => form_vars, :separator => '&' })
    
              @env["rack.input"].rewind
            end
            @env["rack.request.form_input"] = @env["rack.input"]
            @env["rack.request.form_hash"]
          else
            {}
          end
        end
    [](key) click to toggle source

    shortcut for request.params

    # File lib/rack/request.rb, line 269
    def [](key)
      params[key.to_s]
    end
    []=(key, value) click to toggle source

    shortcut for request.params = value

    Note that modifications will not be persisted in the env. Use update_param or delete_param if you want to destructively modify params.

    # File lib/rack/request.rb, line 276
    def []=(key, value)
      params[key.to_s] = value
    end
    accept_encoding() click to toggle source
    # File lib/rack/request.rb, line 336
    def accept_encoding
      parse_http_accept_header(@env["HTTP_ACCEPT_ENCODING"])
    end
    accept_language() click to toggle source
    # File lib/rack/request.rb, line 340
    def accept_language
      parse_http_accept_header(@env["HTTP_ACCEPT_LANGUAGE"])
    end
    base_url() click to toggle source
    # File lib/rack/request.rb, line 317
    def base_url
      url = "#{scheme}://#{host}"
      url << ":#{port}" if port != DEFAULT_PORTS[scheme]
      url
    end
    body() click to toggle source
    # File lib/rack/request.rb, line 20
    def body;            @env["rack.input"]                       end
    content_charset() click to toggle source

    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.

    # File lib/rack/request.rb, line 62
    def content_charset
      media_type_params['charset']
    end
    content_length() click to toggle source
    # File lib/rack/request.rb, line 25
    def content_length;  @env['CONTENT_LENGTH']                   end
    content_type() click to toggle source
    # File lib/rack/request.rb, line 27
    def content_type
      content_type = @env['CONTENT_TYPE']
      content_type.nil? || content_type.empty? ? nil : content_type
    end
    cookies() click to toggle source
    # File lib/rack/request.rb, line 295
    def cookies
      hash   = @env["rack.request.cookie_hash"] ||= {}
      string = @env["HTTP_COOKIE"]
    
      return hash if string == @env["rack.request.cookie_string"]
      hash.clear
    
      # According to RFC 2109:
      #   If multiple cookies satisfy the criteria above, they are ordered in
      #   the Cookie header such that those with more specific Path attributes
      #   precede those with less specific.  Ordering with respect to other
      #   attributes (e.g., Domain) is unspecified.
      cookies = Utils.parse_query(string, ';,') { |s| Rack::Utils.unescape(s) rescue s }
      cookies.each { |k,v| hash[k] = Array === v ? v.first : v }
      @env["rack.request.cookie_string"] = string
      hash
    end
    delete?() click to toggle source

    Checks the HTTP request method (or verb) to see if it was of type DELETE

    # File lib/rack/request.rb, line 116
    def delete?;  request_method == "DELETE"  end
    delete_param(k) click to toggle source

    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 is not touched.

    # File lib/rack/request.rb, line 262
    def delete_param(k)
      v = [ self.POST.delete(k), self.GET.delete(k) ].compact.first
      @params = nil
      v
    end
    form_data?() click to toggle source

    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.

    # File lib/rack/request.rb, line 174
    def form_data?
      type = media_type
      meth = env["rack.methodoverride.original_method"] || env[REQUEST_METHOD]
      (meth == 'POST' && type.nil?) || FORM_DATA_MEDIA_TYPES.include?(type)
    end
    fullpath() click to toggle source
    # File lib/rack/request.rb, line 332
    def fullpath
      query_string.empty? ? path : "#{path}?#{query_string}"
    end
    get?() click to toggle source

    Checks the HTTP request method (or verb) to see if it was of type GET

    # File lib/rack/request.rb, line 119
    def get?;     request_method == GET       end
    head?() click to toggle source

    Checks the HTTP request method (or verb) to see if it was of type HEAD

    # File lib/rack/request.rb, line 122
    def head?;    request_method == HEAD      end
    host() click to toggle source
    # File lib/rack/request.rb, line 106
    def host
      # Remove port number.
      host_with_port.to_s.sub(/:\d+\z/, '')
    end
    host_with_port() click to toggle source
    # File lib/rack/request.rb, line 84
    def host_with_port
      if forwarded = @env["HTTP_X_FORWARDED_HOST"]
        forwarded.split(/,\s?/).last
      else
        @env['HTTP_HOST'] || "#{@env['SERVER_NAME'] || @env['SERVER_ADDR']}:#{@env['SERVER_PORT']}"
      end
    end
    ip() click to toggle source
    # File lib/rack/request.rb, line 348
    def ip
      remote_addrs = split_ip_addresses(@env['REMOTE_ADDR'])
      remote_addrs = reject_trusted_ip_addresses(remote_addrs)
    
      return remote_addrs.first if remote_addrs.any?
    
      forwarded_ips = split_ip_addresses(@env['HTTP_X_FORWARDED_FOR'])
    
      return reject_trusted_ip_addresses(forwarded_ips).last || @env["REMOTE_ADDR"]
    end
    logger() click to toggle source
    # File lib/rack/request.rb, line 34
    def logger;          @env['rack.logger']                      end
    media_type() click to toggle source

    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: www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7

    # File lib/rack/request.rb, line 42
    def media_type
      content_type && content_type.split(/\s*[;,]\s*/, 2).first.downcase
    end
    media_type_params() click to toggle source

    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' }
    # File lib/rack/request.rb, line 51
    def media_type_params
      return {} if content_type.nil?
      Hash[*content_type.split(/\s*[;,]\s*/)[1..-1].
        collect { |s| s.split('=', 2) }.
        map { |k,v| [k.downcase, strip_doublequotes(v)] }.flatten]
    end
    options?() click to toggle source

    Checks the HTTP request method (or verb) to see if it was of type OPTIONS

    # File lib/rack/request.rb, line 125
    def options?; request_method == "OPTIONS" end
    params() click to toggle source

    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.

    # File lib/rack/request.rb, line 229
    def params
      @params ||= self.GET.merge(self.POST)
    rescue EOFError
      self.GET.dup
    end
    parseable_data?() click to toggle source

    Determine whether the request body contains data by checking the request media_type against registered parse-data media-types

    # File lib/rack/request.rb, line 182
    def parseable_data?
      PARSEABLE_DATA_MEDIA_TYPES.include?(media_type)
    end
    patch?() click to toggle source

    Checks the HTTP request method (or verb) to see if it was of type PATCH

    # File lib/rack/request.rb, line 131
    def patch?;   request_method == "PATCH"   end
    path() click to toggle source
    # File lib/rack/request.rb, line 328
    def path
      script_name + path_info
    end
    path_info() click to toggle source
    # File lib/rack/request.rb, line 22
    def path_info;       @env[PATH_INFO].to_s                     end
    path_info=(s) click to toggle source
    # File lib/rack/request.rb, line 112
    def path_info=(s);   @env["PATH_INFO"] = s.to_s               end
    port() click to toggle source
    # File lib/rack/request.rb, line 92
    def port
      if port = host_with_port.split(/:/)[1]
        port.to_i
      elsif port = @env['HTTP_X_FORWARDED_PORT']
        port.to_i
      elsif @env.has_key?("HTTP_X_FORWARDED_HOST")
        DEFAULT_PORTS[scheme]
      elsif @env.has_key?("HTTP_X_FORWARDED_PROTO")
        DEFAULT_PORTS[@env['HTTP_X_FORWARDED_PROTO'].split(',')[0]]
      else
        @env["SERVER_PORT"].to_i
      end
    end
    post?() click to toggle source

    Checks the HTTP request method (or verb) to see if it was of type POST

    # File lib/rack/request.rb, line 134
    def post?;    request_method == "POST"    end
    put?() click to toggle source

    Checks the HTTP request method (or verb) to see if it was of type PUT

    # File lib/rack/request.rb, line 137
    def put?;     request_method == "PUT"     end
    query_string() click to toggle source
    # File lib/rack/request.rb, line 24
    def query_string;    @env[QUERY_STRING].to_s                  end
    referer() click to toggle source

    the referer of the client

    # File lib/rack/request.rb, line 286
    def referer
      @env['HTTP_REFERER']
    end
    Also aliased as: referrer
    referrer() click to toggle source
    Alias for: referer
    request_method() click to toggle source
    # File lib/rack/request.rb, line 23
    def request_method;  @env["REQUEST_METHOD"]                   end
    scheme() click to toggle source
    # File lib/rack/request.rb, line 66
    def scheme
      if @env['HTTPS'] == 'on'
        'https'
      elsif @env['HTTP_X_FORWARDED_SSL'] == 'on'
        'https'
      elsif @env['HTTP_X_FORWARDED_SCHEME']
        @env['HTTP_X_FORWARDED_SCHEME']
      elsif @env['HTTP_X_FORWARDED_PROTO']
        @env['HTTP_X_FORWARDED_PROTO'].split(',')[0]
      else
        @env["rack.url_scheme"]
      end
    end
    script_name() click to toggle source
    # File lib/rack/request.rb, line 21
    def script_name;     @env[SCRIPT_NAME].to_s                   end
    script_name=(s) click to toggle source
    # File lib/rack/request.rb, line 111
    def script_name=(s); @env["SCRIPT_NAME"] = s.to_s             end
    session() click to toggle source
    # File lib/rack/request.rb, line 32
    def session;         @env['rack.session'] ||= {}              end
    session_options() click to toggle source
    # File lib/rack/request.rb, line 33
    def session_options; @env['rack.session.options'] ||= {}      end
    ssl?() click to toggle source
    # File lib/rack/request.rb, line 80
    def ssl?
      scheme == 'https'
    end
    trace?() click to toggle source

    Checks the HTTP request method (or verb) to see if it was of type TRACE

    # File lib/rack/request.rb, line 140
    def trace?;   request_method == "TRACE"   end
    trusted_proxy?(ip) click to toggle source
    # File lib/rack/request.rb, line 344
    def trusted_proxy?(ip)
      ip =~ /\A127\.0\.0\.1\Z|\A(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.|\A::1\Z|\Afd[0-9a-f]{2}:.+|\Alocalhost\Z|\Aunix\Z|\Aunix:/
    end
    update_param(k, v) click to toggle source

    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 is not touched.

    # File lib/rack/request.rb, line 240
    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
      @params = nil
      nil
    end
    url() click to toggle source

    Tries to return a remake of the original request URL as a string.

    # File lib/rack/request.rb, line 324
    def url
      base_url + fullpath
    end
    user_agent() click to toggle source
    # File lib/rack/request.rb, line 291
    def user_agent
      @env['HTTP_USER_AGENT']
    end
    values_at(*keys) click to toggle source

    like Hash#values_at

    # File lib/rack/request.rb, line 281
    def values_at(*keys)
      keys.map{|key| params[key] }
    end
    xhr?() click to toggle source
    # File lib/rack/request.rb, line 313
    def xhr?
      @env["HTTP_X_REQUESTED_WITH"] == "XMLHttpRequest"
    end

    Protected Instance Methods

    parse_http_accept_header(header) click to toggle source
    # File lib/rack/request.rb, line 378
    def parse_http_accept_header(header)
      header.to_s.split(/\s*,\s*/).map do |part|
        attribute, parameters = part.split(/\s*;\s*/, 2)
        quality = 1.0
        if parameters and /\Aq=([\d.]+)/ =~ parameters
          quality = $1.to_f
        end
        [attribute, quality]
      end
    end
    parse_multipart(env) click to toggle source
    # File lib/rack/request.rb, line 374
    def parse_multipart(env)
      Rack::Multipart.parse_multipart(env)
    end
    parse_query(qs) click to toggle source
    # File lib/rack/request.rb, line 368
    def parse_query(qs)
      d = '&'
      qs, d = qs[:query], qs[:separator] if Hash === qs
      Utils.parse_nested_query(qs, d)
    end
    reject_trusted_ip_addresses(ip_addresses) click to toggle source
    # File lib/rack/request.rb, line 364
    def reject_trusted_ip_addresses(ip_addresses)
      ip_addresses.reject { |ip| trusted_proxy?(ip) }
    end
    split_ip_addresses(ip_addresses) click to toggle source
    # File lib/rack/request.rb, line 360
    def split_ip_addresses(ip_addresses)
      ip_addresses ? ip_addresses.strip.split(/[,\s]+/) : []
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!:|=|=Rack/Config.htmlnu[ Class: Rack::Config

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Config

    Rack::Config modifies the environment using the block given during initialization.

    Example:

    use Rack::Config do |env|
      env['my-key'] = 'some-value'
    end

    Public Class Methods

    new(app, &block) click to toggle source
    # File lib/rack/config.rb, line 10
    def initialize(app, &block)
      @app = app
      @block = block
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/config.rb, line 15
    def call(env)
      @block.call(env)
      @app.call(env)
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!2p^^Rack/URLMap.htmlnu[ Class: Rack::URLMap

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::URLMap

    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.

    Public Class Methods

    new(map = {}) click to toggle source
    # File lib/rack/urlmap.rb, line 18
    def initialize(map = {})
      remap(map)
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/urlmap.rb, line 43
    def call(env)
      path = env[PATH_INFO]
      script_name = env['SCRIPT_NAME']
      hHost = env['HTTP_HOST']
      sName = env['SERVER_NAME']
      sPort = env['SERVER_PORT']
    
      @mapping.each do |host, location, match, app|
        unless casecmp?(hHost, host)              || casecmp?(sName, host)              || (!host && (casecmp?(hHost, sName) ||
                          casecmp?(hHost, sName+':'+sPort)))
          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
    remap(map) click to toggle source
    # File lib/rack/urlmap.rb, line 22
    def remap(map)
      @mapping = map.map { |location, app|
        if location =~ %{\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('/', '/+')}(.*)", nil, 'n')
    
        [host, location, match, app]
      }.sort_by do |(host, location, _, _)|
        [host ? -host.size : INFINITY, -location.size]
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!\ABBRack/ContentType.htmlnu[ Class: Rack::ContentType

    Parent

    Methods

    Included Modules

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::ContentType

    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 assumed.

    Public Class Methods

    new(app, content_type = "text/html") click to toggle source
    # File lib/rack/content_type.rb, line 14
    def initialize(app, content_type = "text/html")
      @app, @content_type = app, content_type
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/content_type.rb, line 18
    def call(env)
      status, headers, body = @app.call(env)
      headers = Utils::HeaderHash.new(headers)
    
      unless STATUS_WITH_NO_ENTITY_BODY.include?(status)
        headers[CONTENT_TYPE] ||= @content_type
      end
    
      [status, headers, body]
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!/VVRack/RewindableInput.htmlnu[ Class: Rack::RewindableInput

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::RewindableInput

    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.

    rack.input is required to be rewindable, so if your input stream IO is non-rewindable by nature (e.g. a pipe or a socket) then you can wrap it in an object of this class to easily make it 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.

    Public Class Methods

    new(io) click to toggle source
    # File lib/rack/rewindable_input.rb, line 15
    def initialize(io)
      @io = io
      @rewindable_io = nil
      @unlinked = false
    end

    Public Instance Methods

    close() click to toggle source

    Closes this RewindableInput object without closing the originally wrapped IO oject. Cleans up any temporary resources that this RewindableInput has created.

    This method may be called multiple times. It does nothing on subsequent calls.

    # File lib/rack/rewindable_input.rb, line 46
    def close
      if @rewindable_io
        if @unlinked
          @rewindable_io.close
        else
          @rewindable_io.close!
        end
        @rewindable_io = nil
      end
    end
    each(&block) click to toggle source
    # File lib/rack/rewindable_input.rb, line 31
    def each(&block)
      make_rewindable unless @rewindable_io
      @rewindable_io.each(&block)
    end
    gets() click to toggle source
    # File lib/rack/rewindable_input.rb, line 21
    def gets
      make_rewindable unless @rewindable_io
      @rewindable_io.gets
    end
    read(*args) click to toggle source
    # File lib/rack/rewindable_input.rb, line 26
    def read(*args)
      make_rewindable unless @rewindable_io
      @rewindable_io.read(*args)
    end
    rewind() click to toggle source
    # File lib/rack/rewindable_input.rb, line 36
    def rewind
      make_rewindable unless @rewindable_io
      @rewindable_io.rewind
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!0=u=uRack/Static.htmlnu[ Class: Rack::Static

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Static

    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::File 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"]

    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' => '*'}]
           ]

    Public Class Methods

    new(app, options={}) click to toggle source
    # File lib/rack/static.rb, line 83
    def initialize(app, options={})
      @app = app
      @urls = options[:urls] || ["/favicon.ico"]
      @index = options[:index]
      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.insert(0, [:all, {'Cache-Control' => options[:cache_control]}]) if options[:cache_control]
    
      @file_server = Rack::File.new(root)
    end

    Public Instance Methods

    applicable_rules(path) click to toggle source

    Convert HTTP header rules to HTTP headers

    # File lib/rack/static.rb, line 129
    def applicable_rules(path)
      @header_rules.find_all do |rule, new_headers|
        case rule
        when :all
          true
        when :fonts
          path =~ /\.(?:ttf|otf|eot|woff2|woff|svg)\z/
        when String
          path = ::Rack::Utils.unescape(path)
          path.start_with?(rule) || path.start_with?('/' + rule)
        when Array
          path =~ /\.(#{rule.join('|')})\z/
        when Regexp
          path =~ rule
        else
          false
        end
      end
    end
    call(env) click to toggle source
    # File lib/rack/static.rb, line 109
    def call(env)
      path = env[PATH_INFO]
    
      if can_serve(path)
        env["PATH_INFO"] = (path =~ /\/$/ ? path + @index : @urls[path]) if overwrite_file_path(path)
        path = env["PATH_INFO"]
        response = @file_server.call(env)
    
        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
    can_serve(path) click to toggle source
    # File lib/rack/static.rb, line 105
    def can_serve(path)
      route_file(path) || overwrite_file_path(path)
    end
    overwrite_file_path(path) click to toggle source
    # File lib/rack/static.rb, line 97
    def overwrite_file_path(path)
      @urls.kind_of?(Hash) && @urls.key?(path) || @index && path =~ /\/$/
    end
    route_file(path) click to toggle source
    # File lib/rack/static.rb, line 101
    def route_file(path)
      @urls.kind_of?(Array) && @urls.any? { |url| path.index(url) == 0 }
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!xxRack/Server/Options.htmlnu[ Class: Rack::Server::Options

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Server::Options

    Public Instance Methods

    handler_opts(options) click to toggle source
    # File lib/rack/server.rb, line 106
    def handler_opts(options)
      begin
        info = []
        server = Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
        if server && 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 name.to_s.match(/^(Host|Port)[^a-zA-Z]/) # 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
    parse!(args) click to toggle source
    # File lib/rack/server.rb, line 9
    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("-D", "--daemonize", "run daemonized in the background") { |d|
          options[:daemonize] = d ? true : false
        }
    
        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

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!Lh;lZlZRack/Deflater.htmlnu[ Class: Rack::Deflater

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Deflater

    This middleware enables compression of http responses.

    Currently supported compression algorithms:

    * gzip
    * deflate
    * identity (no transformation)

    The middleware automatically detects when compression is supported and allowed. For example no transformation is made when a cache directive of 'no-transform' is present, or when the response status code is one that doesn't allow an entity body.

    Public Class Methods

    new(app, options = {}) click to toggle source

    Creates Rack::Deflater middleware.

    app

    rack app instance

    options

    hash of deflater options, i.e. 'if' - a lambda enabling / disabling deflation based on returned boolean value

    e.g use Rack::Deflater, :if => lambda { |env, status, headers, body| body.length > 512 }

    'include' - a list of content types that should be compressed

    # File lib/rack/deflater.rb, line 27
    def initialize(app, options = {})
      @app = app
    
      @condition = options[:if]
      @compressible_types = options[:include]
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/deflater.rb, line 34
    def call(env)
      status, headers, body = @app.call(env)
      headers = Utils::HeaderHash.new(headers)
    
      unless should_deflate?(env, status, headers, body)
        return [status, headers, body]
      end
    
      request = Request.new(env)
    
      encoding = Utils.select_best_encoding(%(gzip deflate identity),
                                            request.accept_encoding)
    
      # Set the Vary HTTP header.
      vary = headers["Vary"].to_s.split(",").map { |v| v.strip }
      unless vary.include?("*") || vary.include?("Accept-Encoding")
        headers["Vary"] = vary.push("Accept-Encoding").join(",")
      end
    
      case encoding
      when "gzip"
        headers['Content-Encoding'] = "gzip"
        headers.delete(CONTENT_LENGTH)
        mtime = headers.key?("Last-Modified") ?
          Time.httpdate(headers["Last-Modified"]) : Time.now
        [status, headers, GzipStream.new(body, mtime)]
      when "deflate"
        headers['Content-Encoding'] = "deflate"
        headers.delete(CONTENT_LENGTH)
        [status, headers, DeflateStream.new(body)]
      when "identity"
        [status, headers, body]
      when 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

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!ʡ { {Rack/File.htmlnu[ Class: Rack::File

    In Files

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::File

    Rack::File serves files below the root directory given, according to the path info of the Rack request. e.g. when Rack::File.new("/etc") is used, you can access 'passwd' file as localhost:9292/passwd

    Handlers can detect if bodies are a Rack::File, and use mechanisms like sendfile on the path.

    Attributes

    cache_control[RW]
    path[RW]
    root[RW]
    to_path[RW]

    Public Class Methods

    new(root, headers={}, default_mime = 'text/plain') click to toggle source
    # File lib/rack/file.rb, line 24
    def initialize(root, headers={}, default_mime = 'text/plain')
      @root = root
      @headers = headers
      @default_mime = default_mime
    end

    Public Instance Methods

    _call(env) click to toggle source
    # File lib/rack/file.rb, line 36
    def _call(env)
      unless ALLOWED_VERBS.include? env[REQUEST_METHOD]
        return fail(405, "Method Not Allowed", {'Allow' => ALLOW_HEADER})
      end
    
      path_info = Utils.unescape(env[PATH_INFO])
      clean_path_info = Utils.clean_path_info(path_info)
    
      @path = F.join(@root, clean_path_info)
    
      available = begin
        F.file?(@path) && F.readable?(@path)
      rescue SystemCallError
        false
      end
    
      if available
        serving(env)
      else
        fail(404, "File not found: #{path_info}")
      end
    end
    call(env) click to toggle source
    # File lib/rack/file.rb, line 30
    def call(env)
      dup._call(env)
    end
    each() click to toggle source
    # File lib/rack/file.rb, line 101
    def each
      F.open(@path, "rb") do |file|
        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
    serving(env) click to toggle source
    # File lib/rack/file.rb, line 59
    def serving(env)
      if env["REQUEST_METHOD"] == "OPTIONS"
        return [200, {'Allow' => ALLOW_HEADER, CONTENT_LENGTH => '0'}, []]
      end
      last_modified = F.mtime(@path).httpdate
      return [304, {}, []] if env['HTTP_IF_MODIFIED_SINCE'] == last_modified
    
      headers = { "Last-Modified" => last_modified }
      headers[CONTENT_TYPE] = mime_type if mime_type
    
      # Set custom headers
      @headers.each { |field, content| headers[field] = content } if @headers
    
      response = [ 200, headers, env[REQUEST_METHOD] == "HEAD" ? [] : self ]
    
      size = filesize
    
      ranges = Rack::Utils.byte_ranges(env, size)
      if ranges.nil? || ranges.length > 1
        # No ranges, or multiple ranges (which we don't support):
        # TODO: Support multiple byte-ranges
        response[0] = 200
        @range = 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:
        @range = ranges[0]
        response[0] = 206
        response[1]["Content-Range"] = "bytes #{@range.begin}-#{@range.end}/#{size}"
        size = @range.end - @range.begin + 1
      end
    
      response[2] = [response_body] unless response_body.nil?
    
      response[1][CONTENT_LENGTH] = size.to_s
      response
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!CDD!Rack/MockRequest/FatalWarner.htmlnu[ Class: Rack::MockRequest::FatalWarner

    In Files

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::MockRequest::FatalWarner

    Public Instance Methods

    flush() click to toggle source
    # File lib/rack/mock.rb, line 35
    def flush
    end
    puts(warning) click to toggle source
    # File lib/rack/mock.rb, line 27
    def puts(warning)
      raise FatalWarning, warning
    end
    string() click to toggle source
    # File lib/rack/mock.rb, line 38
    def string
      ""
    end
    write(warning) click to toggle source
    # File lib/rack/mock.rb, line 31
    def write(warning)
      raise FatalWarning, warning
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!|͂W2W2"Rack/MockRequest/FatalWarning.htmlnu[ Class: Rack::MockRequest::FatalWarning

    In Files

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::MockRequest::FatalWarning

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!"X|4@@Rack/Head.htmlnu[ Class: Rack::Head

    In Files

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Head

    Public Class Methods

    new(app) click to toggle source

    Rack::Head returns an empty body for all HEAD requests. It leaves all other requests unchanged.

    # File lib/rack/head.rb, line 8
    def initialize(app)
      @app = app
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/head.rb, line 12
    def call(env)
      status, headers, body = @app.call(env)
    
      if env[REQUEST_METHOD] == HEAD
        [
          status, headers, Rack::BodyProxy.new([]) do
            body.close if body.respond_to? :close
          end
        ]
      else
        [status, headers, body]
      end
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!FFRack/Lobster.htmlnu[ Class: Rack::Lobster

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Lobster

    Paste has a Pony, Rack has a Lobster!

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/lobster.rb, line 32
    def call(env)
      req = Request.new(env)
      if req.GET["flip"] == "left"
        lobster = LobsterString.split("\n").map do |line|
          line.ljust(42).reverse.
            gsub('\', 'TEMP').
            gsub('/', '\').
            gsub('TEMP', '/').
            gsub('{','}').
            gsub('(',')')
        end.join("\n")
        href = "?flip=right"
      elsif req.GET["flip"] == "crash"
        raise "Lobster crashed"
      else
        lobster = LobsterString
        href = "?flip=left"
      end
    
      res = Response.new
      res.write "<title>Lobstericious!</title>"
      res.write "<pre>"
      res.write lobster
      res.write "</pre>"
      res.write "<p><a href='#{href}'>flip!</a></p>"
      res.write "<p><a href='?flip=crash'>crash!</a></p>"
      res.finish
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!*k`??Rack/Logger.htmlnu[ Class: Rack::Logger

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Logger

    Sets up rack.logger to write to rack.errors stream

    Public Class Methods

    new(app, level = ::Logger::INFO) click to toggle source
    # File lib/rack/logger.rb, line 6
    def initialize(app, level = ::Logger::INFO)
      @app, @level = app, level
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/logger.rb, line 10
    def call(env)
      logger = ::Logger.new(env['rack.errors'])
      logger.level = @level
    
      env['rack.logger'] = logger
      @app.call(env)
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!K?^PPRack/Recursive.htmlnu[ Class: Rack::Recursive

    Parent

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Recursive

    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.

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/recursive.rb, line 33
    def initialize(app)
      @app = app
    end

    Public Instance Methods

    _call(env) click to toggle source
    # File lib/rack/recursive.rb, line 41
    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
    call(env) click to toggle source
    # File lib/rack/recursive.rb, line 37
    def call(env)
      dup._call(env)
    end
    include(env, path) click to toggle source
    # File lib/rack/recursive.rb, line 48
    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

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!*CCRack/Runtime.htmlnu[ Class: Rack::Runtime

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Runtime

    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.

    Constants

    FORMAT_STRING

    Public Class Methods

    new(app, name = nil) click to toggle source
    # File lib/rack/runtime.rb, line 9
    def initialize(app, name = nil)
      @app = app
      @header_name = "X-Runtime"
      @header_name << "-#{name}" if name
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/runtime.rb, line 16
    def call(env)
      start_time = clock_time
      status, headers, body = @app.call(env)
      request_time = clock_time - start_time
    
      if !headers.has_key?(@header_name)
        headers[@header_name] = FORMAT_STRING % request_time
      end
    
      [status, headers, body]
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!GtIIRack/Multipart.htmlnu[ Module: Rack::Utils::Multipart

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils::Multipart

    A multipart form data parser, adapted from IOWA.

    Usually, Rack::Request#POST takes care of calling this.

    Public Class Methods

    build_multipart(params, first = true) click to toggle source
    # File lib/rack/multipart.rb, line 28
    def build_multipart(params, first = true)
      Generator.new(params, first).dump
    end
    parse_multipart(env) click to toggle source
    # File lib/rack/multipart.rb, line 24
    def parse_multipart(env)
      Parser.create(env).parse
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!-J-JRack/Chunked/Body.htmlnu[ Class: Rack::Chunked::Body

    Parent

    Methods

    Included Modules

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Chunked::Body

    A body wrapper that emits chunked responses

    Constants

    TAIL
    TERM

    Public Class Methods

    new(body) click to toggle source
    # File lib/rack/chunked.rb, line 17
    def initialize(body)
      @body = body
    end

    Public Instance Methods

    close() click to toggle source
    # File lib/rack/chunked.rb, line 33
    def close
      @body.close if @body.respond_to?(:close)
    end
    each() click to toggle source
    # File lib/rack/chunked.rb, line 21
    def each
      term = TERM
      @body.each do |chunk|
        size = bytesize(chunk)
        next if size == 0
    
        chunk = chunk.dup.force_encoding(Encoding::BINARY) if chunk.respond_to?(:force_encoding)
        yield [size.to_s(16), term, chunk, term].join
      end
      yield TAIL
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!rŢRack/MockRequest.htmlnu[ Class: Rack::MockRequest

    In Files

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::MockRequest

    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.

    Constants

    DEFAULT_ENV

    Public Class Methods

    env_for(uri="", opts={}) click to toggle source

    Return the Rack environment used for a request to uri.

    # File lib/rack/mock.rb, line 88
    def self.env_for(uri="", opts={})
      uri = parse_uri_rfc2396(uri)
      uri.path = "/#{uri.path}" unless uri.path[0] == //
    
      env = DEFAULT_ENV.dup
    
      env[REQUEST_METHOD] = opts[:method] ? opts[:method].to_s.upcase : "GET"
      env["SERVER_NAME"] = uri.host || "example.org"
      env["SERVER_PORT"] = uri.port ? uri.port.to_s : "80"
      env[QUERY_STRING] = uri.query.to_s
      env[PATH_INFO] = (!uri.path || uri.path.empty?) ? "/" : uri.path
      env["rack.url_scheme"] = uri.scheme || "http"
      env["HTTPS"] = env["rack.url_scheme"] == "https" ? "on" : "off"
    
      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 = Utils::Multipart.build_multipart(params)
              opts[:input] = data
              opts["CONTENT_LENGTH"] ||= data.length.to_s
              opts["CONTENT_TYPE"] = "multipart/form-data; boundary=#{Utils::Multipart::MULTIPART_BOUNDARY}"
            else
              opts[:input] = Utils.build_nested_query(params)
            end
          else
            opts[:input] = params
          end
        end
      end
    
      empty_str = ""
      empty_str.force_encoding("ASCII-8BIT") if empty_str.respond_to? :force_encoding
      opts[:input] ||= empty_str
      if String === opts[:input]
        rack_input = StringIO.new(opts[:input])
      else
        rack_input = opts[:input]
      end
    
      rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding)
      env['rack.input'] = rack_input
    
      env["CONTENT_LENGTH"] ||= env["rack.input"].length.to_s
    
      opts.each { |field, value|
        env[field] = value  if String === field
      }
    
      env
    end
    new(app) click to toggle source
    # File lib/rack/mock.rb, line 52
    def initialize(app)
      @app = app
    end
    parse_uri_rfc2396(uri) click to toggle source

    For historical reasons, we're pinning to RFC 2396. It's easier for users and we get support from ruby 1.8 to 2.2 using this method.

    # File lib/rack/mock.rb, line 82
    def self.parse_uri_rfc2396(uri)
      @parser ||= defined?(URI::RFC2396_Parser) ? URI::RFC2396_Parser.new : URI
      @parser.parse(uri)
    end

    Public Instance Methods

    delete(uri, opts={}) click to toggle source
    # File lib/rack/mock.rb, line 60
    def delete(uri, opts={})  request("DELETE", uri, opts)  end
    get(uri, opts={}) click to toggle source
    # File lib/rack/mock.rb, line 56
    def get(uri, opts={})     request("GET", uri, opts)     end
    head(uri, opts={}) click to toggle source
    # File lib/rack/mock.rb, line 61
    def head(uri, opts={})    request("HEAD", uri, opts)    end
    options(uri, opts={}) click to toggle source
    # File lib/rack/mock.rb, line 62
    def options(uri, opts={}) request("OPTIONS", uri, opts) end
    patch(uri, opts={}) click to toggle source
    # File lib/rack/mock.rb, line 59
    def patch(uri, opts={})   request("PATCH", uri, opts)   end
    post(uri, opts={}) click to toggle source
    # File lib/rack/mock.rb, line 57
    def post(uri, opts={})    request("POST", uri, opts)    end
    put(uri, opts={}) click to toggle source
    # File lib/rack/mock.rb, line 58
    def put(uri, opts={})     request("PUT", uri, opts)     end
    request(method="GET", uri="", opts={}) click to toggle source
    # File lib/rack/mock.rb, line 64
    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

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!5TTRack/MockResponse.htmlnu[ Class: Rack::MockResponse

    In Files

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::MockResponse

    Rack::MockResponse provides useful helpers for testing your apps. Usually, you don't create the MockResponse on your own, but use MockRequest.

    Attributes

    errors[RW]

    Errors

    original_headers[R]

    Headers

    Public Class Methods

    new(status, headers, body, errors=StringIO.new("")) click to toggle source
    # File lib/rack/mock.rb, line 164
    def initialize(status, headers, body, errors=StringIO.new(""))
      @original_headers = headers
      @errors           = errors.string if errors.respond_to?(:string)
      @body_string      = nil
    
      super(body, status, headers)
    end

    Public Instance Methods

    =~(other) click to toggle source
    # File lib/rack/mock.rb, line 172
    def =~(other)
      body =~ other
    end
    body() click to toggle source
    # File lib/rack/mock.rb, line 180
    def 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
      super.join
    end
    empty?() click to toggle source
    # File lib/rack/mock.rb, line 194
    def empty?
      [201, 204, 205, 304].include? status
    end
    match(other) click to toggle source
    # File lib/rack/mock.rb, line 176
    def match(other)
      body.match other
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!\fLFFRack/Mime.htmlnu[ Module: Rack::Mime

    In Files

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Mime

    Constants

    MIME_TYPES

    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.

    To add the list mongrel provides, use:

    require 'mongrel/handlers'
    Rack::Mime::MIME_TYPES.merge!(Mongrel::DirHandler::MIME_TYPES)

    Public Class Methods

    match?(value, matcher) click to toggle source

    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
    # File lib/rack/mime.rb, line 28
    def match?(value, matcher)
      v1, v2 = value.split('/', 2)
      m1, m2 = matcher.split('/', 2)
    
      (m1 == '*' || v1 == m1) && (m2.nil? || m2 == '*' || m2 == v2)
    end
    mime_type(ext, fallback='application/octet-stream') click to toggle source

    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')
    # File lib/rack/mime.rb, line 16
    def mime_type(ext, fallback='application/octet-stream')
      MIME_TYPES.fetch(ext.to_s.downcase, fallback)
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!yT8..Rack/Response/Helpers.htmlnu[ Module: Rack::Response::Helpers

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Response::Helpers

    Attributes

    headers[R]

    Headers

    original_headers[R]

    Headers

    Public Instance Methods

    accepted?() click to toggle source
    # File lib/rack/response.rb, line 128
    def accepted?;           status == 202;                        end
    bad_request?() click to toggle source
    # File lib/rack/response.rb, line 129
    def bad_request?;        status == 400;                        end
    client_error?() click to toggle source
    # File lib/rack/response.rb, line 123
    def client_error?;       status >= 400 && status < 500;        end
    content_length() click to toggle source
    # File lib/rack/response.rb, line 150
    def content_length
      cl = headers[CONTENT_LENGTH]
      cl ? cl.to_i : cl
    end
    content_type() click to toggle source
    # File lib/rack/response.rb, line 146
    def content_type
      headers[CONTENT_TYPE]
    end
    created?() click to toggle source
    # File lib/rack/response.rb, line 127
    def created?;            status == 201;                        end
    forbidden?() click to toggle source
    # File lib/rack/response.rb, line 131
    def forbidden?;          status == 403;                        end
    i_m_a_teapot?() click to toggle source
    # File lib/rack/response.rb, line 134
    def i_m_a_teapot?;       status == 418;                        end
    include?(header) click to toggle source
    # File lib/rack/response.rb, line 142
    def include?(header)
      !!headers[header]
    end
    informational?() click to toggle source
    # File lib/rack/response.rb, line 120
    def informational?;      status >= 100 && status < 200;        end
    invalid?() click to toggle source
    # File lib/rack/response.rb, line 118
    def invalid?;            status < 100 || status >= 600;        end
    location() click to toggle source
    # File lib/rack/response.rb, line 155
    def location
      headers["Location"]
    end
    method_not_allowed?() click to toggle source
    # File lib/rack/response.rb, line 133
    def method_not_allowed?; status == 405;                        end
    not_found?() click to toggle source
    # File lib/rack/response.rb, line 132
    def not_found?;          status == 404;                        end
    ok?() click to toggle source
    # File lib/rack/response.rb, line 126
    def ok?;                 status == 200;                        end
    redirect?() click to toggle source
    # File lib/rack/response.rb, line 137
    def redirect?;           [301, 302, 303, 307].include? status; end
    redirection?() click to toggle source
    # File lib/rack/response.rb, line 122
    def redirection?;        status >= 300 && status < 400;        end
    server_error?() click to toggle source
    # File lib/rack/response.rb, line 124
    def server_error?;       status >= 500 && status < 600;        end
    successful?() click to toggle source
    # File lib/rack/response.rb, line 121
    def successful?;         status >= 200 && status < 300;        end
    unauthorized?() click to toggle source
    # File lib/rack/response.rb, line 130
    def unauthorized?;       status == 401;                        end
    unprocessable?() click to toggle source
    # File lib/rack/response.rb, line 135
    def unprocessable?;      status == 422;                        end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!=6BBRack/ForwardRequest.htmlnu[ Class: Rack::ForwardRequest

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::ForwardRequest

    Rack::ForwardRequest gets caught by Rack::Recursive and redirects the current request to the app at url.

    raise ForwardRequest.new("/not-found")

    Attributes

    env[R]
    url[R]

    Public Class Methods

    new(url, env={}) click to toggle source
    # File lib/rack/recursive.rb, line 13
    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

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!)iiRack/ShowExceptions.htmlnu[ Class: Rack::ShowExceptions

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::ShowExceptions

    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.

    Constants

    CONTEXT

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/showexceptions.rb, line 18
    def initialize(app)
      @app = app
      @template = ERB.new(TEMPLATE)
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/showexceptions.rb, line 23
    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 => Rack::Utils.bytesize(body).to_s,
        },
        [body],
      ]
    end
    dump_exception(exception) click to toggle source
    # File lib/rack/showexceptions.rb, line 58
    def dump_exception(exception)
      string = "#{exception.class}: #{exception.message}\n"
      string << exception.backtrace.map { |l| "\t#{l}" }.join("\n")
      string
    end
    prefers_plaintext?(env) click to toggle source
    # File lib/rack/showexceptions.rb, line 49
    def prefers_plaintext?(env)
      !accepts_html(env)
    end
    pretty(env, exception) click to toggle source
    # File lib/rack/showexceptions.rb, line 64
    def pretty(env, exception)
      req = Rack::Request.new(env)
    
      # This double assignment is to prevent an "unused variable" warning on
      # Ruby 1.9.3.  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 on
      # Ruby 1.9.3.  Yes, it is dumb, but I don't like Ruby yelling at me.
      frames = frames = exception.backtrace.map { |line|
        frame = OpenStruct.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

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!~:I:IRack/MethodOverride.htmlnu[ Class: Rack::MethodOverride

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::MethodOverride

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/methodoverride.rb, line 9
    def initialize(app)
      @app = app
    end

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/methodoverride.rb, line 13
    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
    method_override(env) click to toggle source
    # File lib/rack/methodoverride.rb, line 25
    def method_override(env)
      req = Request.new(env)
      method = method_override_param(req) ||
        env[HTTP_METHOD_OVERRIDE_HEADER]
      method.to_s.upcase
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!LLRack/ETag.htmlnu[ Class: Rack::ETag

    In Files

    Parent

    Methods

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::ETag

    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"

    Public Class Methods

    new(app, no_cache_control = nil, cache_control = DEFAULT_CACHE_CONTROL) click to toggle source
    # File lib/rack/etag.rb, line 17
    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

    Public Instance Methods

    call(env) click to toggle source
    # File lib/rack/etag.rb, line 23
    def call(env)
      status, headers, body = @app.call(env)
    
      if etag_status?(status) && etag_body?(body) && !skip_caching?(headers)
        original_body = body
        digest, new_body = digest_body(body)
        body = Rack::BodyProxy.new(new_body) do
          original_body.close if original_body.respond_to?(:close)
        end
        headers[ETAG_STRING] = %(W/"#{digest}") if digest
      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
    
      [status, headers, body]
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!O7|K|KRack/Utils.htmlnu[ Module: Rack::Utils

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::Utils

    Rack::Utils contains a grab-bag of useful methods for writing web applications adopted from all kinds of Ruby libraries.

    Constants

    DEFAULT_SEP
    ESCAPE_HTML
    ESCAPE_HTML_PATTERN

    On 1.8, there is a kcode = 'u' bug that allows for XSS otherwise TODO doesn't apply to jruby, so a better condition above might be preferable?

    HTTP_STATUS_CODES

    Every standard HTTP code mapped to the appropriate message. Generated with: curl -s 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,"'
    Multipart
    PATH_SEPS
    STATUS_WITH_NO_ENTITY_BODY

    Responses with HTTP status codes that should not have an entity body

    SYMBOL_TO_STATUS_CODE

    Attributes

    key_space_limit[RW]
    multipart_part_limit[RW]
    param_depth_limit[RW]

    Public Class Methods

    best_q_match(q_value_header, available_mimes) click to toggle source
    # File lib/rack/utils.rb, line 216
    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 && matches.first
    end
    build_nested_query(value, prefix = nil) click to toggle source
    # File lib/rack/utils.rb, line 185
    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}[#{escape(k)}]" : escape(k))
        }.reject(&:empty?).join('&')
      when nil
        prefix
      else
        raise ArgumentError, "value must be a Hash" if prefix.nil?
        "#{prefix}=#{escape(value)}"
      end
    end
    build_query(params) click to toggle source
    # File lib/rack/utils.rb, line 174
    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
    byte_ranges(env, size) click to toggle source

    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.

    # File lib/rack/utils.rb, line 401
    def byte_ranges(env, size)
      # See <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35>
      http_range = env['HTTP_RANGE']
      return nil unless http_range && http_range =~ /bytes=([^;]+)/
      ranges = []
      $1.split(/,\s*/).each do |range_spec|
        return nil  unless range_spec =~ /(\d*)-(\d*)/
        r0,r1 = $1, $2
        if r0.empty?
          return nil  if r1.empty?
          # 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.empty?
            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
      ranges
    end
    bytesize(string) click to toggle source
    # File lib/rack/utils.rb, line 367
    def bytesize(string)
      string.bytesize
    end
    clean_path_info(path_info) click to toggle source
    # File lib/rack/utils.rb, line 666
    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.unshift '/' if parts.empty? || parts.first.empty?
    
      ::File.join(*clean)
    end
    escape(s) click to toggle source

    URI escapes. (CGI style space to +)

    # File lib/rack/utils.rb, line 34
    def escape(s)
      URI.encode_www_form_component(s)
    end
    escape_html(string) click to toggle source

    Escape ampersands, brackets and quotes to their HTML/XML entities.

    # File lib/rack/utils.rb, line 247
    def escape_html(string)
      string.to_s.gsub(ESCAPE_HTML_PATTERN){|c| ESCAPE_HTML[c] }
    end
    escape_path(s) click to toggle source

    Like URI escaping, but with %20 instead of +. Strictly speaking this is true URI escaping.

    # File lib/rack/utils.rb, line 41
    def escape_path(s)
      escape(s).gsub('+', '%20')
    end
    normalize_params(params, name, v = nil, depth = Utils.param_depth_limit) click to toggle source

    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.

    # File lib/rack/utils.rb, line 133
    def normalize_params(params, name, v = nil, depth = Utils.param_depth_limit)
      raise RangeError if depth <= 0
    
      name =~ %(\A[\[\]]*([^\[\]]+)\]*)
      k = $1 || ''
      after = $' || ''
    
      return if k.empty?
    
      if after == ""
        params[k] = v
      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 =~ %(^\[\]\[([^\[\]]+)\]$) || after =~ %(^\[\](.+)$)
        child_key = $1
        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[k].last.key?(child_key)
          normalize_params(params[k].last, child_key, v, depth - 1)
        else
          params[k] << normalize_params(params.class.new, child_key, v, depth - 1)
        end
      else
        params[k] ||= params.class.new
        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
    
      return params
    end
    params_hash_type?(obj) click to toggle source
    # File lib/rack/utils.rb, line 169
    def params_hash_type?(obj)
      obj.kind_of?(KeySpaceConstrainedParams) || obj.kind_of?(Hash)
    end
    parse_nested_query(qs, d = nil) click to toggle source

    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.

    # File lib/rack/utils.rb, line 115
    def parse_nested_query(qs, d = nil)
      params = KeySpaceConstrainedParams.new
    
      (qs || '').split(d ? /[#{d}] */ : DEFAULT_SEP).each do |p|
        k, v = p.split('=', 2).map { |s| unescape(s) }
    
        normalize_params(params, k, v)
      end
    
      return params.to_params_hash
    rescue ArgumentError => e
      raise InvalidParameterError, e.message
    end
    parse_query(qs, d = nil, &unescaper) click to toggle source

    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 '&;').

    # File lib/rack/utils.rb, line 86
    def parse_query(qs, d = nil, &unescaper)
      unescaper ||= method(:unescape)
    
      params = KeySpaceConstrainedParams.new
    
      (qs || '').split(d ? /[#{d}] */ : 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_params_hash
    end
    q_values(q_value_header) click to toggle source
    # File lib/rack/utils.rb, line 204
    def q_values(q_value_header)
      q_value_header.to_s.split(/\s*,\s*/).map do |part|
        value, parameters = part.split(/\s*;\s*/, 2)
        quality = 1.0
        if md = /\Aq=([\d.]+)/.match(parameters)
          quality = md[1].to_f
        end
        [value, quality]
      end
    end
    rfc2109(time) click to toggle source

    Modified version of stdlib time.rb Time#rfc2822 to use '%d-%b-%Y' instead of '% %b %Y'. It assumes that the time is in GMT to comply to the RFC 2109.

    NOTE: I'm not sure the RFC says it requires GMT, but is ambiguous enough that I'm certain someone implemented only that option. Do not use %a and %b from Time.strptime, it would use localized names for weekday and month.

    # File lib/rack/utils.rb, line 391
    def rfc2109(time)
      wday = Time::RFC2822_DAY_NAME[time.wday]
      mon = Time::RFC2822_MONTH_NAME[time.mon - 1]
      time.strftime("#{wday}, %d-#{mon}-%Y %H:%M:%S GMT")
    end
    rfc2822(time) click to toggle source
    # File lib/rack/utils.rb, line 377
    def rfc2822(time)
      time.rfc2822
    end
    secure_compare(a, b) click to toggle source

    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.

    # File lib/rack/utils.rb, line 437
    def secure_compare(a, b)
      return false unless bytesize(a) == bytesize(b)
    
      l = a.unpack("C*")
    
      r, i = 0, -1
      b.each_byte { |v| r |= v ^ l[i+=1] }
      r == 0
    end
    select_best_encoding(available_encodings, accept_encoding) click to toggle source
    # File lib/rack/utils.rb, line 252
    def select_best_encoding(available_encodings, accept_encoding)
      # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
    
      expanded_accept_encoding =
        accept_encoding.map { |m, q|
          if m == "*"
            (available_encodings - accept_encoding.map { |m2, _| m2 }).map { |m2| [m2, q] }
          else
            [[m, q]]
          end
        }.inject([]) { |mem, list|
          mem + list
        }
    
      encoding_candidates = expanded_accept_encoding.sort_by { |_, q| -q }.map { |m, _| m }
    
      unless encoding_candidates.include?("identity")
        encoding_candidates.push("identity")
      end
    
      expanded_accept_encoding.each { |m, q|
        encoding_candidates.delete(m) if q == 0.0
      }
    
      return (encoding_candidates & available_encodings)[0]
    end
    status_code(status) click to toggle source
    # File lib/rack/utils.rb, line 653
    def status_code(status)
      if status.is_a?(Symbol)
        SYMBOL_TO_STATUS_CODE[status] || 500
      else
        status.to_i
      end
    end
    unescape(s, encoding = Encoding::UTF_8) click to toggle source
    # File lib/rack/utils.rb, line 49
    def unescape(s, encoding = Encoding::UTF_8)
      URI.decode_www_form_component(s, encoding)
    end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!dCCRack/NullLogger.htmlnu[ Class: Rack::NullLogger

    Files

    Class/Module Index [+]

    Quicksearch

    Rack::NullLogger

    Public Class Methods

    new(app) click to toggle source
    # File lib/rack/nulllogger.rb, line 3
    def initialize(app)
      @app = app
    end

    Public Instance Methods

    <<(msg) click to toggle source
    # File lib/rack/nulllogger.rb, line 35
    def <<(msg); end
    add(severity, message = nil, progname = nil, &block) click to toggle source
    # File lib/rack/nulllogger.rb, line 34
    def add(severity, message = nil, progname = nil, &block); end
    call(env) click to toggle source
    # File lib/rack/nulllogger.rb, line 7
    def call(env)
      env['rack.logger'] = self
      @app.call(env)
    end
    close() click to toggle source
    # File lib/rack/nulllogger.rb, line 33
    def close ; end
    datetime_format() click to toggle source
    # File lib/rack/nulllogger.rb, line 25
    def datetime_format ; end
    datetime_format=(datetime_format) click to toggle source
    # File lib/rack/nulllogger.rb, line 30
    def datetime_format=(datetime_format); end
    debug(progname = nil, &block) click to toggle source
    # File lib/rack/nulllogger.rb, line 13
    def debug(progname = nil, &block); end
    debug?() click to toggle source
    # File lib/rack/nulllogger.rb, line 19
    def debug? ; end
    error(progname = nil, &block) click to toggle source
    # File lib/rack/nulllogger.rb, line 15
    def error(progname = nil, &block); end
    error?() click to toggle source
    # File lib/rack/nulllogger.rb, line 21
    def error? ; end
    fatal(progname = nil, &block) click to toggle source
    # File lib/rack/nulllogger.rb, line 16
    def fatal(progname = nil, &block); end
    fatal?() click to toggle source
    # File lib/rack/nulllogger.rb, line 22
    def fatal? ; end
    formatter() click to toggle source
    # File lib/rack/nulllogger.rb, line 26
    def formatter ; end
    formatter=(formatter) click to toggle source
    # File lib/rack/nulllogger.rb, line 31
    def formatter=(formatter); end
    info(progname = nil, &block) click to toggle source
    # File lib/rack/nulllogger.rb, line 12
    def info(progname = nil, &block); end
    info?() click to toggle source
    # File lib/rack/nulllogger.rb, line 18
    def info? ;  end
    level() click to toggle source
    # File lib/rack/nulllogger.rb, line 23
    def level ; end
    level=(level) click to toggle source
    # File lib/rack/nulllogger.rb, line 28
    def level=(level); end
    progname() click to toggle source
    # File lib/rack/nulllogger.rb, line 24
    def progname ; end
    progname=(progname) click to toggle source
    # File lib/rack/nulllogger.rb, line 29
    def progname=(progname); end
    sev_threshold() click to toggle source
    # File lib/rack/nulllogger.rb, line 27
    def sev_threshold ; end
    sev_threshold=(sev_threshold) click to toggle source
    # File lib/rack/nulllogger.rb, line 32
    def sev_threshold=(sev_threshold); end
    unknown(progname = nil, &block) click to toggle source
    # File lib/rack/nulllogger.rb, line 17
    def unknown(progname = nil, &block); end
    warn(progname = nil, &block) click to toggle source
    # File lib/rack/nulllogger.rb, line 14
    def warn(progname = nil, &block); end
    warn?() click to toggle source
    # File lib/rack/nulllogger.rb, line 20
    def warn? ;  end

    [Validate]

    Generated with the Darkfish Rdoc Generator 2.

    PK!DDlib/rack/conditionalget_rb.htmlnu[ File: conditionalget.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/utils

    Description

    PK!lib/rack/multipart_rb.htmlnu[ File: multipart.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!QI1bblib/rack/lint_rb.htmlnu[ File: lint.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/utils
    • forwardable

    Description

    PK!>pClib/rack/handler/cgi_rb.htmlnu[ File: cgi.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/content_length
    • rack/rewindable_input

    Description

    PK!Vdkk,lib/rack/handler/swiftiplied_mongrel_rb.htmlnu[ File: swiftiplied_mongrel.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • swiftcore/swiftiplied_mongrel

    Description

    PK!\cc(lib/rack/handler/evented_mongrel_rb.htmlnu[ File: evented_mongrel.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • swiftcore/evented_mongrel

    Description

    PK!A?lib/rack/handler/thin_rb.htmlnu[ File: thin.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • thin
    • rack/content_length
    • rack/chunked

    Description

    PK! lib/rack/handler/mongrel_rb.htmlnu[ File: mongrel.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • mongrel
    • stringio
    • rack/content_length
    • rack/chunked

    Description

    PK!판 lib/rack/handler/fastcgi_rb.htmlnu[ File: fastcgi.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • fcgi
    • socket
    • rack/content_length
    • rack/rewindable_input

    Description

    PK!ko\lib/rack/handler/scgi_rb.htmlnu[ File: scgi.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • scgi
    • stringio
    • rack/content_length
    • rack/chunked

    Description

    PK!lib/rack/handler/lsws_rb.htmlnu[ File: lsws.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • lsapi
    • rack/content_length
    • rack/rewindable_input

    Description

    PK!  lib/rack/handler/webrick_rb.htmlnu[ File: webrick.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • webrick
    • stringio
    • rack/content_length

    Description

    PK!|LMlib/rack/urlmap_rb.htmlnu[ File: urlmap.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!^lib/rack/mock_rb.htmlnu[ File: mock.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • uri
    • stringio
    • rack
    • rack/lint
    • rack/utils
    • rack/response

    Description

    PK!5lib/rack/utils_rb.htmlnu[ File: utils.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • fileutils
    • set
    • tempfile
    • rack/multipart
    • time
    • rack/backports/uri/common_18
    • rack/backports/uri/common_192
    • rack/backports/uri/common_193
    • uri/common

    Description

    PK!).lib/rack/lobster_rb.htmlnu[ File: lobster.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • zlib
    • rack/request
    • rack/response
    • rack
    • rack/showexceptions

    Description

    PK!İ[lib/rack/body_proxy_rb.htmlnu[ File: body_proxy.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!&lib/rack/runtime_rb.htmlnu[ File: runtime.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!!lib/rack/session/memcache_rb.htmlnu[ File: memcache.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/session/abstract/id
    • memcache

    Description

    AUTHOR: blink <blinketje@gmail.com>; blinkruby-lang@irc.freenode.net

    PK!즢lib/rack/session/cookie_rb.htmlnu[ File: cookie.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • openssl
    • zlib
    • rack/request
    • rack/response
    • rack/session/abstract/id

    Description

    PK!y׮*CClib/rack/session/pool_rb.htmlnu[ File: pool.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/session/abstract/id
    • thread

    Description

    AUTHOR: blink <blinketje@gmail.com>; blinkruby-lang@irc.freenode.net THANKS:

    apeiros, for session id generation, expiry setup, and threadiness
    sergio, threadiness and bugreps
    PK!?!77$lib/rack/session/abstract/id_rb.htmlnu[ File: id.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • time
    • rack/request
    • rack/response
    • securerandom

    Description

    AUTHOR: blink <blinketje@gmail.com>; blinkruby-lang@irc.freenode.net bugrep: Andreas Zehnder

    PK!kHYYlib/rack/server_rb.htmlnu[ File: server.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • optparse
    • pp

    Description

    PK!Yp: lib/rack/static_rb.htmlnu[ File: static.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!==lib/rack/request_rb.htmlnu[ File: request.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/utils

    Description

    PK!u??lib/rack/head_rb.htmlnu[ File: head.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/body_proxy

    Description

    PK!rΫlib/rack/showexceptions_rb.htmlnu[ File: showexceptions.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • ostruct
    • erb
    • rack/request
    • rack/utils

    Description

    PK! X1pplib/rack/content_length_rb.htmlnu[ File: content_length.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/utils
    • rack/body_proxy

    Description

    PK!jBBlib/rack/content_type_rb.htmlnu[ File: content_type.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/utils

    Description

    PK!&N!66(lib/rack/backports/uri/common_18_rb.htmlnu[ File: common_18.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!+p77)lib/rack/backports/uri/common_193_rb.htmlnu[ File: common_193.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!/Ϩ77)lib/rack/backports/uri/common_192_rb.htmlnu[ File: common_192.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!8++(lib/rack/multipart/uploaded_file_rb.htmlnu[ File: uploaded_file.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!qc0''$lib/rack/multipart/generator_rb.htmlnu[ File: generator.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!uлKK!lib/rack/multipart/parser_rb.htmlnu[ File: parser.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/utils

    Description

    PK!뀠JJ lib/rack/tempfile_reaper_rb.htmlnu[ File: tempfile_reaper.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/body_proxy

    Description

    PK!WT lib/rack/utils/okjson_rb.htmlnu[ File: okjson.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • stringio

    Description

    Copyright 2011, 2012 Keith Rarick

    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.

    PK!l@ilib/rack/response_rb.htmlnu[ File: response.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/request
    • rack/utils
    • rack/body_proxy
    • time

    Description

    PK!,lib/rack/methodoverride_rb.htmlnu[ File: methodoverride.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!xbblib/rack/lock_rb.htmlnu[ File: lock.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • thread
    • rack/body_proxy

    Description

    PK!LLlib/rack/reloader_rb.htmlnu[ File: reloader.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • pathname

    Description

       Copyright (c) 2009 Michael Fellinger m.fellinger@gmail.com
    Rack::Reloader is subject to the terms of an MIT-style license.

    See COPYING or www.opensource.org/licenses/mit-license.php.

    PK!4&`lib/rack/builder_rb.htmlnu[ File: builder.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!lib/rack/nulllogger_rb.htmlnu[ File: nulllogger.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK! lib/rack/cascade_rb.htmlnu[ File: cascade.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!Bдlib/rack/file_rb.htmlnu[ File: file.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • time
    • rack/utils
    • rack/mime

    Description

    PK! >2kk!lib/rack/rewindable_input_rb.htmlnu[ File: rewindable_input.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • tempfile
    • rack/utils

    Description

    PK!*LYY"lib/rack/auth/digest/nonce_rb.htmlnu[ File: nonce.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • digest/md5

    Description

    PK!Wl** lib/rack/auth/digest/md5_rb.htmlnu[ File: md5.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/auth/abstract/handler
    • rack/auth/digest/request
    • rack/auth/digest/params
    • rack/auth/digest/nonce
    • digest/md5

    Description

    PK!Y$lib/rack/auth/digest/request_rb.htmlnu[ File: request.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/auth/abstract/request
    • rack/auth/digest/params
    • rack/auth/digest/nonce

    Description

    PK!'O33#lib/rack/auth/digest/params_rb.htmlnu[ File: params.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK! ڭlib/rack/auth/basic_rb.htmlnu[ File: basic.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/auth/abstract/handler
    • rack/auth/abstract/request

    Description

    PK!]]&lib/rack/auth/abstract/request_rb.htmlnu[ File: request.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/request

    Description

    PK!44&lib/rack/auth/abstract/handler_rb.htmlnu[ File: handler.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!,::lib/rack/etag_rb.htmlnu[ File: etag.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • digest/md5

    Description

    PK!RF88lib/rack/logger_rb.htmlnu[ File: logger.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • logger

    Description

    PK!Llib/rack/directory_rb.htmlnu[ File: directory.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • time
    • rack/utils
    • rack/mime

    Description

    PK!3L:==lib/rack/chunked_rb.htmlnu[ File: chunked.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/utils

    Description

    PK!Dlib/rack/handler_rb.htmlnu[ File: handler.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK!`JZ88lib/rack/recursive_rb.htmlnu[ File: recursive.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • uri

    Description

    PK!qlib/rack/deflater_rb.htmlnu[ File: deflater.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • zlib
    • time
    • rack/utils

    Description

    PK!?Zlib/rack/showstatus_rb.htmlnu[ File: showstatus.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • erb
    • rack/request
    • rack/utils

    Description

    PK!R8zGGlib/rack/commonlogger_rb.htmlnu[ File: commonlogger.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/body_proxy

    Description

    PK!Ovlib/rack/mime_rb.htmlnu[ File: mime.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK! Ilib/rack/config_rb.htmlnu[ File: config.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    PK! fNiilib/rack/sendfile_rb.htmlnu[ File: sendfile.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires
    • rack/file
    • rack/body_proxy

    Description

    PK!(`'OOlib/rack_rb.htmlnu[ File: rack.rb [rack-1.6.4 Documentation]
    Last Modified
    2019-12-05 17:59:30 -0500
    Requires

    Description

    Copyright (C) 2007, 2008, 2009, 2010 Christian Neukirchen <purl.org/net/chneukirchen>

    Rack is freely distributable under the terms of an MIT-style license. See COPYING or www.opensource.org/licenses/mit-license.php.

    PK!qll version.rbnu[PK!pmarkup/heading.rbnu[PK!ھmarkup/attributes.rbnu[PK!ԄEE markup/list.rbnu[PK!hP)1markup/to_joined_paragraph.rbnu[PK!g\''smarkup/to_html.rbnu[PK!ua1l@markup/to_bs.rbnu[PK!V>Gmarkup/to_test.rbnu[PK! Lmarkup/table.rbnu[PK!eM0Pmarkup/to_html_snippet.rbnu[PK!ТRfmarkup/indented_paragraph.rbnu[PK! t{ll(jmarkup/to_markdown.rbnu[PK!fQ`66xmarkup/to_ansi.rbnu[PK!&#[[Pmarkup/to_label.rbnu[PK!C"==markup/include.rbnu[PK!WY kmarkup/document.rbnu[PK!fcrEmarkup/list_item.rbnu[PK!;;bmarkup/rule.rbnu[PK!ߦoۡmarkup/attr_changer.rbnu[PK!%Fɣmarkup/formatter.rbnu[PK!ܹmarkup/to_rdoc.rbnu[PK!ʘw  8markup/to_tt_only.rbnu[PK!M markup/raw.rbnu[PK!''markup/attribute_manager.rbnu[PK!y  markup/hard_break.rbnu[PK!tԇ markup/blank_line.rbnu[PK!N_ markup/block_quote.rbnu[PK!TZLmarkup/to_table_of_contents.rbnu[PK!a{{'markup/to_html_crossref.rbnu[PK![nA##)markup/verbatim.rbnu[PK!|Q/markup/regexp_handling.rbnu[PK!dh2markup/paragraph.rbnu[PK!v!!4markup/pre_process.rbnu[PK!WVmarkup/attr_span.rbnu[PK!p9C99jYmarkup/parser.rbnu[PK! !VHerbio.rbnu[PK!#"VVrd.rbnu[PK!T߆text.rbnu[PK!Ȅ anon_class.rbnu[PK!; options.rbnu[PK!ѓ#R))Lstats.rbnu[PK! wi18n.rbnu[PK!&“ xrequire.rbnu[PK!  |mixin.rbnu[PK!ٔyy @context.rbnu[PK!n"generator/pot/message_extractor.rbnu[PK!jl{ generator/pot/po_entry.rbnu[PK!=generator/pot/po.rbnu[PK!&generator/pot.rbnu[PK!r .Z$generator/template/json_index/js/navigation.jsnu[PK!P^,\/generator/template/json_index/js/searcher.jsnu[PK!2+D<|Igenerator/template/darkfish/_sidebar_table_of_contents.rhtmlnu[PK!>qq0Ngenerator/template/darkfish/fonts/Lato-Light.ttfnu[PK!䍒TtTt8generator/template/darkfish/fonts/Lato-RegularItalic.ttfnu[PK!^b8o5generator/template/darkfish/fonts/SourceCodePro-Bold.ttfnu[PK!՞ww2Qgenerator/template/darkfish/fonts/Lato-Regular.ttfnu[PK!Zoo6 generator/template/darkfish/fonts/Lato-LightItalic.ttfnu[PK!I;g: generator/template/darkfish/fonts/SourceCodePro-Regular.ttfnu[PK!TB3X generator/template/darkfish/_sidebar_in_files.rhtmlnu[PK!@@'Y generator/template/darkfish/index.rhtmlnu[PK!3^^)4\ generator/template/darkfish/_footer.rhtmlnu[PK!7'] generator/template/darkfish/class.rhtmlnu[PK! O2]]4+t generator/template/darkfish/_sidebar_installed.rhtmlnu[PK! NNN3u generator/template/darkfish/servlet_not_found.rhtmlnu[PK!QCC3w generator/template/darkfish/_sidebar_sections.rhtmlnu[PK!  3Cy generator/template/darkfish/table_of_contents.rhtmlnu[PK!Љ5cc2 generator/template/darkfish/_sidebar_classes.rhtmlnu[PK!E`2t generator/template/darkfish/_sidebar_methods.rhtmlnu[PK!53v generator/template/darkfish/_sidebar_includes.rhtmlnu[PK!΍  ( generator/template/darkfish/js/search.jsnu[PK!ll]D D * generator/template/darkfish/js/darkfish.jsnu[PK!g:3 generator/template/darkfish/_sidebar_VCS_info.rhtmlnu[PK!{wj.Ǡ generator/template/darkfish/servlet_root.rhtmlnu[PK!h˟ee0* generator/template/darkfish/images/tag_green.pngnu[PK!=V: generator/template/darkfish/images/bullet_toggle_minus.pngnu[PK!S*( generator/template/darkfish/images/bug.pngnu[PK!0 , generator/template/darkfish/images/brick.pngnu[PK!$V2 generator/template/darkfish/images/macFFBgHack.pngnu[PK!Zmm1ٲ generator/template/darkfish/images/page_green.pngnu[PK!(VV6 generator/template/darkfish/images/page_white_text.pngnu[PK!P-c generator/template/darkfish/images/delete.pngnu[PK!Os~* generator/template/darkfish/images/add.pngnu[PK!CCJUU.½ generator/template/darkfish/images/package.pngnu[PK!(?Y3u generator/template/darkfish/images/bullet_black.pngnu[PK!)oHH4^ generator/template/darkfish/images/wrench_orange.pngnu[PK!7 + generator/template/darkfish/images/zoom.pngnu[PK!"557 generator/template/darkfish/images/page_white_width.pngnu[PK!Utt/ generator/template/darkfish/images/arrow_up.pngnu[PK!R71 generator/template/darkfish/images/brick_link.pngnu[PK!bb- generator/template/darkfish/images/wrench.pngnu[PK!Err+ generator/template/darkfish/images/date.pngnu[PK!#۸PP+q generator/template/darkfish/images/ruby.pngnu[PK!zz1 generator/template/darkfish/_sidebar_parent.rhtmlnu[PK!޹5 generator/template/darkfish/_sidebar_navigation.rhtmlnu[PK!32generator/template/darkfish/_sidebar_extends.rhtmlnu[PK!h C))(<generator/template/darkfish/css/rdoc.cssnu[PK!;9Iv)/.generator/template/darkfish/css/fonts.cssnu[PK!` e&|Ggenerator/template/darkfish/page.rhtmlnu[PK!e0Igenerator/template/darkfish/_sidebar_pages.rhtmlnu[PK!]WDqq'Mgenerator/template/darkfish/_head.rhtmlnu[PK!*f1Qgenerator/template/darkfish/_sidebar_search.rhtmlnu[PK! Tgenerator/markup.rbnu[PK!qagenerator/json_index.rbnu[PK!P Q Qgenerator/darkfish.rbnu[PK!f=wgenerator/ri.rbnu[PK!v($($method_attr.rbnu[PK!ʥ9e }tom_doc.rbnu[PK!Detask.rbnu[PK!- % %1code_object.rbnu[PK!S2 Vi18n/text.rbnu[PK!KzVf f bi18n/locale.rbnu[PK!(.ZZ6lstore.rbnu[PK!^t; markup.rbnu[PK!vTDODOclass_module.rbnu[PK!KK g6generator.rbnu[PK!/ =include.rbnu[PK! >extend.rbnu[PK!Pn ?markdown.rbnu[PK!e3 Ttoken_stream.rbnu[PK!H"-- atop_level.rbnu[PK!#@@(xstats/quiet.rbnu[PK! {stats/verbose.rbnu[PK!9)-$00stats/normal.rbnu[PK!R:Icontext/section.rbnu[PK!Lcode_objects.rbnu[PK!R5-ghost_method.rbnu[PK!^ any_method.rbnu[PK!c7 comment.rbnu[PK!W*single_class.rbnu[PK!OG!!imarkdown/entities.rbnu[PK!9((έmarkdown/literals.rbnu[PK!p-}} alias.rbnu[PK!epC0meta_method.rbnu[PK!He}normal_class.rbnu[PK!sBrubygems_hook.rbnu[PK!% s66Wrdoc.rbnu[PK!8KKH5cross_reference.rbnu[PK!,lVQnormal_module.rbnu[PK!y Wencoding.rbnu[PK!bb]] gconstant.rbnu[PK!Luerb_partial.rbnu[PK! [>  owattr.rbnu[PK!:ܶ parser/rd.rbnu[PK!T͋͋ parser/c.rbnu[PK!733parser/text.rbnu[PK! />>parser/ripper_state_lex.rbnu[PK!U5Uparser/simple.rbnu[PK!4QՆ  [parser/ruby_tools.rbnu[PK!_Aeparser/markdown.rbnu[PK!5nnhparser/ruby.rbnu[PK!h\;!;!Tparser/changelog.rbnu[PK!5s00 0vservlet.rbnu[PK!'vv_ri.rbnu[PK!}} rd/inline_parser.rbnu[PK!] &rd/inline.rbnu[PK!('Y'Y,rd/block_parser.rbnu[PK!. ;m #known_classes.rbnu[PK!n== !ri/task.rbnu[PK!tUU ri/store.rbnu[PK!Vnrr(ri/formatter.rbnu[PK! Ų^^ ٗri/paths.rbnu[PK!=], rri/driver.rbnu[PK!x8W 8parser.rbnu[PK!~'@@VWEBrick/HTTPResponse.htmlnu[PK!E4B#0#0 FCGI.htmlnu[PK! 11 index.htmlnu[PK!K<<jFCGI/Stream.htmlnu[PK!+L;0;0 [WEBrick.htmlnu[PK!}5}5(rdoc.cssnu[PK! |;ff ^js/jquery.jsnu[PK!$ js/darkfish.jsnu[PK!/qZZjs/thickbox-compressed.jsnu[PK!S< Vjs/quicksearch.jsnu[PK!=ۏ6FF created.ridnu[PK!ܽ11 8 Object.htmlnu[PK!h˟ee5 images/tag_green.pngnu[PK!=V7 images/bullet_toggle_minus.pngnu[PK!S8 images/bug.pngnu[PK!0 < images/brick.pngnu[PK!$V> images/macFFBgHack.pngnu[PK!Zmm2? images/page_green.pngnu[PK!(VVA images/page_white_text.pngnu[PK!CCJUUC images/package.pngnu[PK!(?YG images/bullet_black.pngnu[PK!Q5H images/loadingAnimation.gifnu[PK!J~_ images/find.pngnu[PK! OOPb images/plugin.pngnu[PK!=kd images/bullet_toggle_plus.pngnu[PK!>)oHHe images/wrench_orange.pngnu[PK!7 h images/zoom.pngnu[PK!"55k images/page_white_width.pngnu[PK!R7m images/brick_link.pngnu[PK!bbBp images/wrench.pngnu[PK!Errr images/date.pngnu[PK!#۸PPu images/ruby.pngnu[PK! ?4?4%x KNOWN-ISSUES.htmlnu[PK!$  Rack.htmlnu[PK!v,96962!Rack/Session.htmlnu[PK!;[22+Mi!Rack/Multipart/MultipartPartLimitError.htmlnu[PK!O-ee6!Rack/Multipart/Parser.htmlnu[PK!\HH""Rack/Multipart/Generator.htmlnu[PK!X$R$R 7K"Rack/Multipart/UploadedFile.htmlnu[PK!lG$88"Rack/Auth.htmlnu[PK!.zޏޏ"Rack/Response.htmlnu[PK!7BBg#Rack/TempfileReaper.htmlnu[PK! "H"HU#Rack/ContentLength.htmlnu[PK!Ns)KK#Rack/Chunked.htmlnu[PK!e#Jg^^=$Rack/Sendfile.htmlnu[PK!-H.LLƜ$Rack/ShowStatus.htmlnu[PK!H22$$Rack/Handler/SwiftipliedMongrel.htmlnu[PK!&HM{M{%Rack/Handler/Mongrel.htmlnu[PK!1hhk%Rack/Handler/SCGI.htmlnu[PK!07zzE&Rack/Handler/WEBrick.htmlnu[PK! t.ZZ|&Rack/Handler/CGI.htmlnu[PK!S22 &Rack/Handler/EventedMongrel.htmlnu[PK!kw[w[ 'Rack/Handler/LSWS.htmlnu[PK!8҄mmpf'Rack/Handler/FastCGI.htmlnu[PK!b$JJ='Rack/Handler/Thin.htmlnu[PK!kqB}}(Rack/Utils/HeaderHash.htmlnu[PK!33" (Rack/Utils/ParameterTypeError.htmlnu[PK![ ^Z^Zq(Rack/Utils/OkJson.htmlnu[PK!D0303%+)Rack/Utils/InvalidParameterError.htmlnu[PK!c~Ѱ33^)Rack/Utils/OkJson/Error.htmlnu[PK!_33 )Rack/Utils/OkJson/Utf8Error.htmlnu[PK!s'NN)Rack/Utils/Context.htmlnu[PK!eڄ_V_V)*Rack/Utils/KeySpaceConstrainedParams.htmlnu[PK!%VVk*Rack/Cascade.htmlnu[PK!7MN:N:*Rack/Lint.htmlnu[PK!u66k*Rack/Directory.htmlnu[PK! r99"+Rack/RewindableInput/Tempfile.htmlnu[PK!4<<+Rack/Auth/AbstractHandler.htmlnu[PK!0 C CB ,Rack/Auth/Basic/Request.htmlnu[PK!lPDQDQO,Rack/Auth/AbstractRequest.htmlnu[PK!s%=77+,Rack/Auth/Digest.htmlnu[PK!ģ M?M?&,Rack/Auth/Basic.htmlnu[PK!OQg_g_-Rack/Auth/Digest/Nonce.htmlnu[PK!:l/ddix-Rack/Auth/Digest/Params.htmlnu[PK!m)=XX<-Rack/Auth/Digest/Request.htmlnu[PK!MN(W(W6.Rack/Auth/Digest/MD5.htmlnu[PK!c2c2.Rack/Lint/ErrorWrapper.htmlnu[PK!g=e2e2.Rack/Lint/HijackWrapper.htmlnu[PK!6`wC2C2T.Rack/Lint/LintError.htmlnu[PK!c2c2%/Rack/Lint/InputWrapper.htmlnu[PK!TTX/Rack/BodyProxy.htmlnu[PK!(3fGG f/Rack/Deflater/DeflateStream.htmlnu[PK!e%KKV/Rack/Deflater/GzipStream.htmlnu[PK!aXATFTF'A0Rack/CommonLogger.htmlnu[PK!9BB0Rack/Lock.htmlnu[PK!ISS0Rack/Reloader/Stat.htmlnu[PK!n:~:~1Rack/Builder.htmlnu[PK!I8o8o1Rack/Handler.htmlnu[PK!vIUIU 2Rack/Reloader.htmlnu[PK!b2Rack/Server.htmlnu[PK!v |H|H2Rack/ConditionalGet.htmlnu[PK!Xአnn73Rack/Session/Memcache.htmlnu[PK!*+IQaQa3Rack/Session/Pool.htmlnu[PK!B3V5V5I4Rack/Session/Abstract.htmlnu[PK!#+FAFA'=4Rack/Session/Cookie/Base64/Marshal.htmlnu[PK!xvkBB$4Rack/Session/Cookie/Base64/JSON.htmlnu[PK!qqCqC'4Rack/Session/Cookie/Base64/ZipJSON.htmlnu[PK!l:@@[5Rack/Session/Cookie/Base64.htmlnu[PK!?r==!G5Rack/Session/Cookie/Identity.htmlnu[PK!W#yGyG5Rack/Session/Cookie.htmlnu[PK!ڙtPSPSF5Rack/Session/Abstract/ID.htmlnu[PK!Ȗ& 6Rack/Session/Abstract/SessionHash.htmlnu[PK!e6Rack/Request.htmlnu[PK!:|=|=f8Rack/Config.htmlnu[PK!2p^^8Rack/URLMap.htmlnu[PK!\ABBt9Rack/ContentType.htmlnu[PK!/VV[F9Rack/RewindableInput.htmlnu[PK!0=u=u9Rack/Static.htmlnu[PK!xx):Rack/Server/Options.htmlnu[PK!Lh;lZlZ:Rack/Deflater.htmlnu[PK!ʡ { {:Rack/File.htmlnu[PK!CDD!`;Rack/MockRequest/FatalWarner.htmlnu[PK!|͂W2W2">;Rack/MockRequest/FatalWarning.htmlnu[PK!"X|4@@;Rack/Head.htmlnu[PK!FF<Rack/Lobster.htmlnu[PK!*k`??`<Rack/Logger.htmlnu[PK!K?^PPp<Rack/Recursive.htmlnu[PK!*CCl<Rack/Runtime.htmlnu[PK!GtII<4=Rack/Multipart.htmlnu[PK!-J-J}=Rack/Chunked/Body.htmlnu[PK!rŢ=Rack/MockRequest.htmlnu[PK!5TTg>Rack/MockResponse.htmlnu[PK!\fLFFC>Rack/Mime.htmlnu[PK!yT8..?Rack/Response/Helpers.htmlnu[PK!=6BB?Rack/ForwardRequest.htmlnu[PK!)ii?Rack/ShowExceptions.htmlnu[PK!~:I:IH@Rack/MethodOverride.htmlnu[PK!LL:@Rack/ETag.htmlnu[PK!O7|K|K@Rack/Utils.htmlnu[PK!dCCB*BRack/NullLogger.htmlnu[PK!DDBlib/rack/conditionalget_rb.htmlnu[PK!\Blib/rack/multipart_rb.htmlnu[PK!QI1bbBlib/rack/lint_rb.htmlnu[PK!>pCeBlib/rack/handler/cgi_rb.htmlnu[PK!Vdkk,4Blib/rack/handler/swiftiplied_mongrel_rb.htmlnu[PK!\cc(Blib/rack/handler/evented_mongrel_rb.htmlnu[PK!A?Blib/rack/handler/thin_rb.htmlnu[PK! Blib/rack/handler/mongrel_rb.htmlnu[PK!판 Blib/rack/handler/fastcgi_rb.htmlnu[PK!ko\Blib/rack/handler/scgi_rb.htmlnu[PK!Blib/rack/handler/lsws_rb.htmlnu[PK!  Clib/rack/handler/webrick_rb.htmlnu[PK!|LM Clib/rack/urlmap_rb.htmlnu[PK!^Clib/rack/mock_rb.htmlnu[PK!5QClib/rack/utils_rb.htmlnu[PK!).6Clib/rack/lobster_rb.htmlnu[PK!İ[Y$Clib/rack/body_proxy_rb.htmlnu[PK!&)Clib/rack/runtime_rb.htmlnu[PK!!/Clib/rack/session/memcache_rb.htmlnu[PK!즢?5Clib/rack/session/cookie_rb.htmlnu[PK!y׮*CC;Clib/rack/session/pool_rb.htmlnu[PK!?!77$BClib/rack/session/abstract/id_rb.htmlnu[PK!kHYYHClib/rack/server_rb.htmlnu[PK!Yp: :NClib/rack/static_rb.htmlnu[PK!==SClib/rack/request_rb.htmlnu[PK!u??YClib/rack/head_rb.htmlnu[PK!rΫ^Clib/rack/showexceptions_rb.htmlnu[PK! X1ppdClib/rack/content_length_rb.htmlnu[PK!jBB^jClib/rack/content_type_rb.htmlnu[PK!&N!66(oClib/rack/backports/uri/common_18_rb.htmlnu[PK!+p77){uClib/rack/backports/uri/common_193_rb.htmlnu[PK!/Ϩ77) {Clib/rack/backports/uri/common_192_rb.htmlnu[PK!8++(Clib/rack/multipart/uploaded_file_rb.htmlnu[PK!qc0''$Clib/rack/multipart/generator_rb.htmlnu[PK!uлKK!Clib/rack/multipart/parser_rb.htmlnu[PK!뀠JJ 5Clib/rack/tempfile_reaper_rb.htmlnu[PK!WT ϖClib/rack/utils/okjson_rb.htmlnu[PK!l@iClib/rack/response_rb.htmlnu[PK!,Clib/rack/methodoverride_rb.htmlnu[PK!xbb Clib/rack/lock_rb.htmlnu[PK!LLClib/rack/reloader_rb.htmlnu[PK!4&`IClib/rack/builder_rb.htmlnu[PK!Clib/rack/nulllogger_rb.htmlnu[PK!  Clib/rack/cascade_rb.htmlnu[PK!BдiClib/rack/file_rb.htmlnu[PK! >2kk!/Clib/rack/rewindable_input_rb.htmlnu[PK!*LYY"Clib/rack/auth/digest/nonce_rb.htmlnu[PK!Wl** Clib/rack/auth/digest/md5_rb.htmlnu[PK!Y$Clib/rack/auth/digest/request_rb.htmlnu[PK!'O33#6Clib/rack/auth/digest/params_rb.htmlnu[PK! ڭClib/rack/auth/basic_rb.htmlnu[PK!]]&Clib/rack/auth/abstract/request_rb.htmlnu[PK!44&KClib/rack/auth/abstract/handler_rb.htmlnu[PK!,::Clib/rack/etag_rb.htmlnu[PK!RF88TDlib/rack/logger_rb.htmlnu[PK!LDlib/rack/directory_rb.htmlnu[PK!3L:== Dlib/rack/chunked_rb.htmlnu[PK!D(Dlib/rack/handler_rb.htmlnu[PK!`JZ88Dlib/rack/recursive_rb.htmlnu[PK!qDlib/rack/deflater_rb.htmlnu[PK!?Z#Dlib/rack/showstatus_rb.htmlnu[PK!R8zGG)Dlib/rack/commonlogger_rb.htmlnu[PK!Ov9/Dlib/rack/mime_rb.htmlnu[PK! I4Dlib/rack/config_rb.htmlnu[PK! fNii9Dlib/rack/sendfile_rb.htmlnu[PK!(`'OO?Dlib/rack_rb.htmlnu[PKmm.FD