<commit_before>package Mojo::DOM;
use Mojo::Base -base;
use overload
  '%{}'    => sub { shift->attr },
  'bool'   => sub {1},
  '""'     => sub { shift->to_xml },
  fallback => 1;

# "Fry: This snow is beautiful. I'm glad global warming never happened.
#  Leela: Actually, it did. But thank God nuclear winter canceled it out."
use Carp 'croak';
use Mojo::Collection;
use Mojo::DOM::CSS;
use Mojo::DOM::HTML;
use Mojo::Util qw(deprecated squish);
use Scalar::Util qw(blessed weaken);

sub AUTOLOAD {
  my $self = shift;

  my ($package, $method) = our $AUTOLOAD =~ /^([\w:]+)::(\w+)$/;
  croak "Undefined subroutine &${package}::$method called"
    unless blessed $self && $self->isa(__PACKAGE__);

  # Search children of current element
  my $children = $self->children($method);
  return @$children > 1 ? $children : $children->[0] if @$children;
  croak qq{Can't locate object method "$method" via package "$package"};
}

sub DESTROY { }

sub new {
  my $class = shift;
  my $self = bless [Mojo::DOM::HTML->new], ref $class || $class;
  return @_ ? $self->parse(@_) : $self;
}

sub all_text {
  my $tree = shift->tree;
  return _text(_elements($tree), 1, _trim($tree, @_));
}

sub append { shift->_add(1, @_) }

sub append_content {
  my ($self, $new) = @_;
  my $tree = $self->tree;
  push @$tree, @{_parent($self->_parse("$new"), $tree)};
  return $self;
}

sub at { shift->find(@_)->[0] }

sub attr {
  my $self = shift;

  # Hash
  my $tree = $self->tree;
  my $attrs = $tree->[0] eq 'root' ? {} : $tree->[2];
  return $attrs unless @_;

  # Get
  return $attrs->{$_[0]} // '' unless @_ > 1 || ref $_[0];

  # Set
  %$attrs = (%$attrs, %{ref $_[0] ? $_[0] : {@_}});

  return $self;
}

# DEPRECATED in Top Hat!
sub attrs {
  deprecated 'Mojo::DOM::attrs is DEPRECATED in favor of Mojo::DOM::attr';
  shift->attr(@_);
}

sub children {
  my ($self, $type) = @_;

  my @children;
  my $xml  = $self->xml;
  my $tree = $self->tree;
  for my $e (@$tree[($tree->[0] eq 'root' ? 1 : 4) .. $#$tree]) {

    # Make sure child is the right type
    next if $e->[0] ne 'tag' || (defined $type && $e->[1] ne $type);
    push @children, $self->new->tree($e)->xml($xml);
  }

  return Mojo::Collection->new(@children);
}

sub content_xml {
  my $self = shift;

  # Render children individually
  my $tree = $self->tree;
  my $xml  = $self->xml;
  return join '',
    map { Mojo::DOM::HTML->new(tree => $_, xml => $xml)->render }
    @$tree[($tree->[0] eq 'root' ? 1 : 4) .. $#$tree];
}

sub find {
  my ($self, $selector) = @_;
  my $xml = $self->xml;
  my $results = Mojo::DOM::CSS->new(tree => $self->tree)->select($selector);
  return Mojo::Collection->new(map { $self->new->tree($_)->xml($xml) }
      @$results);
}

sub namespace {
  my $self = shift;

  # Extract namespace prefix and search parents
  return '' if (my $current = $self->tree)->[0] eq 'root';
  my $ns = $current->[1] =~ /^(.*?):/ ? "xmlns:$1" : undef;
  while ($current->[0] ne 'root') {

    # Namespace for prefix
    my $attrs = $current->[2];
    if ($ns) { /^\Q$ns\E$/ and return $attrs->{$_} for keys %$attrs }

    # Namespace attribute
    elsif (defined $attrs->{xmlns}) { return $attrs->{xmlns} }

    # Parent
    $current = $current->[3];
  }

  return '';
}

sub next { shift->_sibling(1) }

sub parent {
  my $self = shift;
  return undef if (my $tree = $self->tree)->[0] eq 'root';
  return $self->new->tree($tree->[3])->xml($self->xml);
}

sub parse { shift->_html(parse => shift) }

sub prepend { shift->_add(0, @_) }

sub prepend_content {
  my ($self, $new) = @_;
  my $tree = $self->tree;
  splice @$tree, $tree->[0] eq 'root' ? 1 : 4, 0,
    @{_parent($self->_parse("$new"), $tree)};
  return $self;
}

sub previous { shift->_sibling(0) }

sub remove { shift->replace('') }

sub replace {
  my ($self, $new) = @_;
  my $tree = $self->tree;
  return $self->xml(undef)->parse($new) if $tree->[0] eq 'root';
  return $self->_replace($tree, $self->_parse("$new"));
}

sub strip {
  my $self = shift;
  my $tree = $self->tree;
  return $self if $tree->[0] eq 'root';
  return $self->_replace($tree, ['root', @$tree[4 .. $#$tree]]);
}

sub replace_content {
  my ($self, $new) = @_;
  my $tree = $self->tree;
  splice @$tree, $tree->[0] eq 'root' ? 1 : 4, $#$tree,
    @{_parent($self->_parse("$new"), $tree)};
  return $self;
}

sub root {
  my $self = shift;

  my $root = $self->tree;
  while ($root->[0] eq 'tag') {
    last unless my $parent = $root->[3];
    $root = $parent;
  }

  return $self->new->tree($root)->xml($self->xml);
}

sub text {
  my $tree = shift->tree;
  return _text(_elements($tree), 0, _trim($tree, @_));
}

sub text_after {
  my ($self, $trim) = @_;

  # Find following text elements
  return '' if (my $tree = $self->tree)->[0] eq 'root';
  my (@elements, $started);
  for my $e (@{_elements($tree->[3])}) {
    ++$started and next if $e eq $tree;
    next unless $started;
    last if $e->[0] eq 'tag';
    push @elements, $e;
  }

  return _text(\@elements, 0, _trim($tree->[3], $trim));
}<commit_msg>fixed Mojo::DOM formatting<commit_after>package Mojo::DOM;
use Mojo::Base -base;
use overload
  '%{}'    => sub { shift->attr },
  'bool'   => sub {1},
  '""'     => sub { shift->to_xml },
  fallback => 1;

# "Fry: This snow is beautiful. I'm glad global warming never happened.
#  Leela: Actually, it did. But thank God nuclear winter canceled it out."
use Carp 'croak';
use Mojo::Collection;
use Mojo::DOM::CSS;
use Mojo::DOM::HTML;
use Mojo::Util qw(deprecated squish);
use Scalar::Util qw(blessed weaken);

sub AUTOLOAD {
  my $self = shift;

  my ($package, $method) = our $AUTOLOAD =~ /^([\w:]+)::(\w+)$/;
  croak "Undefined subroutine &${package}::$method called"
    unless blessed $self && $self->isa(__PACKAGE__);

  # Search children of current element
  my $children = $self->children($method);
  return @$children > 1 ? $children : $children->[0] if @$children;
  croak qq{Can't locate object method "$method" via package "$package"};
}

sub DESTROY { }

sub new {
  my $class = shift;
  my $self = bless [Mojo::DOM::HTML->new], ref $class || $class;
  return @_ ? $self->parse(@_) : $self;
}

sub all_text {
  my $tree = shift->tree;
  return _text(_elements($tree), 1, _trim($tree, @_));
}

sub append { shift->_add(1, @_) }

sub append_content {
  my ($self, $new) = @_;
  my $tree = $self->tree;
  push @$tree, @{_parent($self->_parse("$new"), $tree)};
  return $self;
}

sub at { shift->find(@_)->[0] }

sub attr {
  my $self = shift;

  # Hash
  my $tree = $self->tree;
  my $attrs = $tree->[0] eq 'root' ? {} : $tree->[2];
  return $attrs unless @_;

  # Get
  return $attrs->{$_[0]} // '' unless @_ > 1 || ref $_[0];

  # Set
  %$attrs = (%$attrs, %{ref $_[0] ? $_[0] : {@_}});

  return $self;
}

# DEPRECATED in Top Hat!
sub attrs {
  deprecated 'Mojo::DOM::attrs is DEPRECATED in favor of Mojo::DOM::attr';
  shift->attr(@_);
}

sub children {
  my ($self, $type) = @_;

  my @children;
  my $xml  = $self->xml;
  my $tree = $self->tree;
  for my $e (@$tree[($tree->[0] eq 'root' ? 1 : 4) .. $#$tree]) {

    # Make sure child is the right type
    next if $e->[0] ne 'tag' || (defined $type && $e->[1] ne $type);
    push @children, $self->new->tree($e)->xml($xml);
  }

  return Mojo::Collection->new(@children);
}

sub content_xml {
  my $self = shift;

  # Render children individually
  my $tree = $self->tree;
  my $xml  = $self->xml;
  return join '',
    map { Mojo::DOM::HTML->new(tree => $_, xml => $xml)->render }
    @$tree[($tree->[0] eq 'root' ? 1 : 4) .. $#$tree];
}

sub find {
  my ($self, $selector) = @_;
  my $xml = $self->xml;
  my $results = Mojo::DOM::CSS->new(tree => $self->tree)->select($selector);
  return Mojo::Collection->new(map { $self->new->tree($_)->xml($xml) }
      @$results);
}

sub namespace {
  my $self = shift;

  # Extract namespace prefix and search parents
  return '' if (my $current = $self->tree)->[0] eq 'root';
  my $ns = $current->[1] =~ /^(.*?):/ ? "xmlns:$1" : undef;
  while ($current->[0] ne 'root') {

    # Namespace for prefix
    my $attrs = $current->[2];
    if ($ns) { /^\Q$ns\E$/ and return $attrs->{$_} for keys %$attrs }

    # Namespace attribute
    elsif (defined $attrs->{xmlns}) { return $attrs->{xmlns} }

    # Parent
    $current = $current->[3];
  }

  return '';
}

sub next { shift->_sibling(1) }

sub parent {
  my $self = shift;
  return undef if (my $tree = $self->tree)->[0] eq 'root';
  return $self->new->tree($tree->[3])->xml($self->xml);
}

sub parse { shift->_html(parse => shift) }

sub prepend { shift->_add(0, @_) }

sub prepend_content {
  my ($self, $new) = @_;
  my $tree = $self->tree;
  splice @$tree, $tree->[0] eq 'root' ? 1 : 4, 0,
    @{_parent($self->_parse("$new"), $tree)};
  return $self;
}

sub previous { shift->_sibling(0) }

sub remove { shift->replace('') }

sub replace {
  my ($self, $new) = @_;
  my $tree = $self->tree;
  return $self->xml(undef)->parse($new) if $tree->[0] eq 'root';
  return $self->_replace($tree, $self->_parse("$new"));
}

sub replace_content {
  my ($self, $new) = @_;
  my $tree = $self->tree;
  splice @$tree, $tree->[0] eq 'root' ? 1 : 4, $#$tree,
    @{_parent($self->_parse("$new"), $tree)};
  return $self;
}

sub root {
  my $self = shift;

  my $root = $self->tree;
  while ($root->[0] eq 'tag') {
    last unless my $parent = $root->[3];
    $root = $parent;
  }

  return $self->new->tree($root)->xml($self->xml);
}

sub strip {
  my $self = shift;
  my $tree = $self->tree;
  return $self if $tree->[0] eq 'root';
  return $self->_replace($tree, ['root', @$tree[4 .. $#$tree]]);
}

sub text {
  my $tree = shift->tree;
  return _text(_elements($tree), 0, _trim($tree, @_));
}

sub text_after {
  my ($self, $trim) = @_;

  # Find following text elements
  return '' if (my $tree = $self->tree)->[0] eq 'root';
  my (@elements, $started);
  for my $e (@{_elements($tree->[3])}) {
    ++$started and next if $e eq $tree;
    next unless $started;
    last if $e->[0] eq 'tag';
    push @elements, $e;
  }

  return _text(\@elements, 0, _trim($tree->[3], $trim));
}
{'fraction_non_alphanumeric': 0.22478845196615233, 'fraction_numerical': 0.0101543056246889, 'mean_word_length': 3.3773420479302834, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 201, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 44}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2681272', 'n_tokens_mistral': 3939, 'n_tokens_neox': 3846, 'n_words': 1034}