#!/usr/bin/perl

# $Id: komkindex.pl,v 1.2 2007/07/22 04:12:15 karnes Exp $
#
### Copyrihgt (C) 2004-2007 Dohyun Kim <nomos at ktug.or.kr>
###
### -------------------------------------------------------------------
### part of ko.TeX
###
### This work may be distributed and/or modified under the
### conditions of the LaTeX Project Public License, either version 1.3c
### of this license or (at your option) any later version.
### The latest version of this license is in
###  http://www.latex-project.org/lppl.txt
### and version 1.3c or later is part of all distributions of LaTeX
### version 2006/05/20 or later.
### -------------------------------------------------------------------
###
### TODO: how to distinguish malformed utf8 string in IND file?
###

#use warnings;
#use strict;
use 5.8.0;
use Getopt::Std;

## -euc option
for (@ARGV) {
    if ( /^\-+euc/ ) {
        $_ = '';
        exec ("hmakeindex @ARGV") or die "couldn't exec hmakeindex: $!";
    }
}

binmode STDOUT,":utf8";

my $progname = $0;
$progname =~ s/^.*\///;

print "This is $progname, a makeindex wrapper for ko.TeX package.\n";

@ARGV == 0 and die "\n",
  "Usage: $progname [-euc] [makeindex options] idx_filename[s]\n",
  "       -euc: exec hmakeindex, passing other arguments as they are.\n\n",
  "       $progname [-k] [makeindex options] idx_filename[s]\n",
  "       -k: put hangul index entries before than others.\n\n";


###
### Many thanks to Jinsuk Kim, http://www.jinsuk.pe.kr
###
my @hanja_to_hangul = get_hanja_hangul_table("hanja_hg.tab");
my @hanjacompat_to_hangul = get_hanja_hangul_table("hjcom_hg.tab");
my @hanjaextA_to_hangul = get_hanja_hangul_table("hjexa_hg.tab");

my @cjamo_jamo =
  qw/
     1100 1101 11aa 1102 11ac 11ad 1103 1104
     1105 11b0 11b1 11b2 11b3 11b4 11b5 111a
     1106 1107 1108 1121 1109 110a 110b 110c
     110d 110e 110f 1110 1111 1112 1161 1162
     1163 1164 1165 1166 1167 1168 1169 116a
     116b 116c 116d 116e 116f 1170 1171 1172
     1173 1174 1175 1160 1114 1115 11c7 11c8
     11cc 11ce 11d3 11d7 11d9 111c 11dd 11df
     111d 111e 1120 1122 1123 1127 1129 112b
     112c 112d 112e 112f 1132 1136 1140 1147
     114c 11f1 11f2 1157 1158 1159 1184 1185
     1188 1191 1192 1194 119e 11a1
     /;

my @hangul_grouping =
  qw/
     F785 F788 F790 F798 F7A8 F7AE F7C2 F7D8
     F7D9 F7E7 F7E8 F7F0 F7F5 F7F6 F7F8 F7FC
     F7FF F807 F80C F811 F816 F81B F828 F831
     F83C F846 F84F F85E F86B
     /;
#     ㄱ   ㄴ   ㄷ   ㄹ   ㅁ   ㅂ   ㅅ   ㅿ
#     ㅇ   ㆁ   ㅈ   ㅊ   ㅋ   ㅌ   ㅍ   ㅎ
#     ㆆ   ㅏ   ㅑ   ㅓ   ㅕ   ㅗ   ㅛ   ㅜ
#     ㅠ   ㅡ   ㅣ   ㆍ   종성


###
### parse options
###
my (
    %args,
    @IDXfiles,
    $istfile,
    $indfile,
    $logfile,
    $idx0
   );
getopts('kcgilo:p:qrs:t:LT',\%args);
@IDXfiles = @ARGV or die "No .idx file specified!\n";

if ($args{s}) {
  $istfile = $args{s};
  $istfile =~ s/(\.ist)?$/\.ist/;
}

$idx0 = $IDXfiles[0];
$idx0 =~s/\.idx$//;

$indfile = $args{o} || $idx0;
$indfile =~ /(\..+?)$/ or $indfile .= ".ind";

$logfile = $args{t} || $idx0;
$logfile =~ /(\..+?)$/ or $logfile .= ".ilg";

foreach my $file (@IDXfiles) {
  $file =~ /(\..+?)$/ or $file .= ".idx";
}

###
### read .ist file
###
my $ist_heading_flag = 0;
my $ist_heading_prefix = '';
my $ist_heading_suffix = '';
my $ist_group_skip = '\indexspace';
my $ist_item_0 = '\item ';
my $ist_delim_0 = ', ';
my $ist_keyword = '\indexentry';
my $ist_actual = '@';
my $ist_encap = '|';
my $ist_level = '!';
my $ist_quote = '"';
my $ist_arg_open = '{';
my $ist_arg_close = '}';
my $ist_postamble = '\end{theindex}';

if ($istfile) {
  $istfile = `kpsewhich $istfile`;
  chomp $istfile;
  open IST,"<:utf8",$istfile or die "$args{s} : $!\n";
  while (<IST>) {
    s/\%.*//;
    s/\\n\b//g;
    s/\\\\/\\/g;
    if (/headings_flag\s+(.+)/) {
      $ist_heading_flag = $1;
    } elsif (/heading_prefix\s+"(.*)"/) {
      $ist_heading_prefix = $1;
    } elsif (/heading_suffix\s+"(.*)"/) {
      $ist_heading_suffix = $1;
    } elsif (/group_skip\s+"(.*)"/) {
      $ist_group_skip = $1;
    } elsif (/item_0\s+"(.*)"/) {
      $ist_item_0 = $1;
    } elsif (/delim_0\s+"(.*)"/) {
      $ist_delim_0 = $1;
    } elsif (/keyword\s+"(.*)"/) {
      $ist_keyword = $1;
    } elsif (/actual\s+'(.*)'/) {
      $ist_actual = $1;
    } elsif (/encap\s+'(.*)'/) {
      $ist_encap = $1;
    } elsif (/level\s+'(.*)'/) {
      $ist_level = $1;
    } elsif (/quote\s+'(.*)'/) {
      $ist_quote = $1;
    } elsif (/arg_open\s+'(.*)'/) {
      $ist_arg_open = $1;
    } elsif (/arg_close\s+'(.*)'/) {
      $ist_arg_close = $1;
    } elsif (/postamble\s+"(.*)"/) {
      $ist_postamble = $1;
    }
  }
  close IST;
}


# prepare to run makeindex
my $makeindexoption = "-i -o $indfile -t $logfile";
foreach ('c','l','q','r','L','g','T') {
  $makeindexoption .= " -$_" if $args{$_};
}
$makeindexoption .= " -s $istfile" if $args{s};
$makeindexoption .= " -p $args{p}" if $args{p};

###
### read .idx files
###
my ( @idxarr, %idxhash );
foreach my $file (@IDXfiles) {
  open IDX,"<:utf8",$file or die "$file : $!\n";
  while (<IDX>) {
    s/\^\^([0-9a-f]{2})/pack "U0C", hex $1/ge;
    s/\\unihangulchar\s*\{(\d+)\}/chr $1/ge;

    #    \indexentry{ ..... }{ .. }
    # -> $pre         $body $post
    if (/(\Q$ist_keyword\E\s*\Q$ist_arg_open\E)
         (.*?[^\Q$ist_quote\E])
         (\Q$ist_arg_close$ist_arg_open\E.+?\Q$ist_arg_close\E)
         $/x) {
      my($pre,$body,$post) = ($1,$2,$3);

      #    \indexentry{ ..... | .. }{ .. }
      # -> $pre         $body $post
      my @xbody = split /(?<!\Q$ist_quote\E)\Q$ist_encap/,$body;
      for ( my $i=$#xbody; $i>0; $i--) {
        $post = $ist_encap.$xbody[$i].$post;
      }
      $body = $xbody[0];
        
      # !을 경계로 가름.
      @xbody = split /(?<!\Q$ist_quote\E)\Q$ist_level/, $body;

      for (@xbody) {
        # @이 없으면... 넣어준다.
        unless (/[^\Q$ist_quote\E]\Q$ist_actual/) {
          $_ = $_.$ist_actual.$_;
        }

        # @을 경계로 가름.
        my @ybody = split /(?<!\Q$ist_quote\E])\Q$ist_actual\E/, $_;
        $_ = $ybody[0];

        &hanja_to_hangul;
        s/([\x{AC00}-\x{D7A3}])/syllable_to_jamo_chr($1)/ge;
        s/([\x{3131}-\x{318E}])/cjamo_to_jamo_chr($1)/ge;
        &insert_fillers;
        &decompose_jamo;
        &jamo_to_puajamo;

        s/^([\x{80}-\x{F784}\x{F8F8}-\x{FFFF}])/symbolize_first($1)/e;

        $ybody[0] = $_;

        my @tmp = split "",$ybody[0];
        $idxhash{ $ybody[1] } = $tmp[0];	# for grouping routine
        if ( $tmp[0] =~ /^\x{F801}/ ) {   # 초성채움.
          $idxhash{ $ybody[1] } = $tmp[1];
        }
        if ( $tmp[0] =~ /^\x{F806}/ ) {   # 중성채움.
          $idxhash{ $ybody[1] } = $tmp[2];
        }

        $_ = join $ist_actual,@ybody;
      }
      $body = join $ist_level,@xbody;
      push @idxarr,"$pre$body$post\n";
    }
  }
  close IDX;
}


###
### run makeindex
###
open(MAKE,"| makeindex $makeindexoption") or die "Cannot fork: $!\n";
binmode MAKE,":utf8";
print MAKE @idxarr;
close MAKE;
$? >> 8 and die "\nmakeindex failed!\n";

###
### read .ind file and group hangul items
###
my @indarr;
my $indgroup = 0;
# (indgroup) 0 = header;
#            1 = latin;
#            2 = hangul;
#            3 = footer.

my $cho = -1;

open IND,"<:utf8",$indfile or die "$indfile : $!\n";
while (<IND>) {
  if (/\Q$ist_postamble\E/) {
    $indgroup = 3;
  } elsif ($ist_heading_flag and
           /\Q$ist_heading_prefix\E/) {
    if (/\Q$ist_heading_prefix\E.+?\Q$ist_heading_suffix\E/) {
      ### 깨진 글자가 index head로 하나 들어가는데 이를 제거하기 위해
      ### 복잡하게 이중으로 조건검사를 하였다. 깨진 글자는 두번째 조건을
      ### 통과하지 못한다.
      $indgroup++ if $indgroup == 0;
    } else {
      next;
    }
  } elsif (/\Q$ist_item_0\E(.+?)(\Q$ist_delim_0\E|$)/ ) {
    my $body = $1;
    if ( $idxhash{$body} =~ /[\x{F785}-\x{F8F7}]/ ) {
      $indgroup++ if $indgroup == 1;
      my $first = get_hindexhead_num($idxhash{$body});
      if ($first != $cho) {
        my $tmp = '';
        $tmp .= "\n$ist_group_skip\n" if $cho >= 0;
        $tmp .= "$ist_heading_prefix\\hindexhead{$first}$ist_heading_suffix\n"
          if ($ist_heading_flag);
        $_ = $tmp.$_;
        $cho = $first;
      }
    } else {
      $indgroup++ if $indgroup == 0;
    }
  }
  push @{$indarr[$indgroup]} , $_;
}
close IND;


open IND,">:utf8",$indfile or die "$indfile : $!\n";
if ($args{k}) {
  # latin의 마지막 indexspace를 hangul 마지막으로 이동. (-k 옵션에서)
  if ( @{ $indarr[1] } and @{ $indarr[2] } ) {
    my $tmp;
    $tmp = pop @{ $indarr[1] }
      until ( $tmp =~ /\Q$ist_group_skip\E/ );
    push @{ $indarr[2] },$tmp;
  }

  for my $i (0,2,1,3) {
    for my $j (0 .. $#{$indarr[$i]} ) {
      print IND $indarr[$i][$j];
    }
  }
} else {
  for my $i (0..3) {
    for my $j (0 .. $#{$indarr[$i]} ) {
      print IND $indarr[$i][$j];
    }
  }
}
close IND;


########## SUBROUTINES ##########

sub get_hindexhead_num {
  my $fn = ord shift;

  for ( my $i=0; $i<@hangul_grouping; $i++ ) {

    my $divval = $fn / hex($hangul_grouping[$i]);
    if ( $divval < 1 ) {
      return --$i;
    }
  }
}

sub symbolize_first {
  my $first = shift;
  my $symfirst = '';

  for (unpack("U0C*", $first)) {
    $symfirst .= sprintf "^^%02x",$_;
  }

  return $symfirst;
}

sub syllable_to_jamo_chr {
  my $syl  = ord shift;

  my $cho  = ($syl - 0xac00) / (21 * 28) + 0x1100;
  my $jung = ($syl - 0xac00) % (21 * 28) / 28 + 0x1161;
  my $jong = ($syl - 0xac00) % 28 + 0x11a7;

  # do not delete U+11A7
  return chr($cho).chr($jung).chr($jong);
}

sub cjamo_to_jamo_chr {
  my $cj = ord shift;
  $cj = hex $cjamo_jamo[$cj - 0x3131];
  if($cj <= 0x115f) { ### choseong: append U+11A7
    return chr($cj).chr(0x1160).chr(0x11A7);
  }
  elsif($cj >= 0x1160 and $cj <= 0x11a2) { ### jungseong: append U+11A7
    return chr(0x115f).chr($cj).chr(0x11A7);
  }
  else { ### jongseong
    return chr(0x115f).chr(0x1160).chr($cj);
  }
}

sub insert_fillers {
  s/^([\x{1160}-\x{11A2}])/\x{115F}$1/;
  s/^([\x{11A7}-\x{11F9}])/\x{115F}\x{1160}$1/;
  s/([\x{1100}-\x{115F}])([\x{11A7}-\x{11F9}])/$1\x{1160}\x{11A7}\x{115F}\x{1160}$2/g;
  s/([\x{1100}-\x{115F}])([^\x{1100}-\x{11A2}])/$1\x{1160}$2/g;
  s/([\x{1160}-\x{11A2}])([^\x{1160}-\x{11F9}])/$1\x{11A7}$2/g;
  s/([\x{1100}-\x{115F}])$/$1\x{1160}\x{11A7}/;
  s/([\x{1160}-\x{11A2}])$/$1\x{11A7}/;
}

sub hanja_to_hangul {
  s/([\x{3400}-\x{4DB5}])/chr $hanjaextA_to_hangul[ord($1)-0x3400]/ge;
  s/([\x{4E00}-\x{9FA5}])/chr $hanja_to_hangul[ord($1)-0x4E00]/ge;
  s/([\x{F900}-\x{FA2D}])/chr $hanjacompat_to_hangul[ord($1)-0xF900]/ge;
}

sub get_hanja_hangul_table {
  my $file = shift;
  my @HJHG;

  $file = `kpsewhich $file`;
  chomp $file;

  open TAB, $file or die "$file : $!\n";
  @HJHG = <TAB>;
  close TAB;

  chomp @HJHG;
  return @HJHG;
}

sub decompose_jamo {
  s/\x{112C}/\x{1107}\x{1107}\x{110B}/g;
  s/\x{1122}/\x{1107}\x{1109}\x{1100}/g;
  s/\x{1123}/\x{1107}\x{1109}\x{1103}/g;
  s/\x{1124}/\x{1107}\x{1109}\x{1107}/g;
  s/\x{1125}/\x{1107}\x{1109}\x{1109}/g;
  s/\x{1126}/\x{1107}\x{1109}\x{110C}/g;
  s/\x{1133}/\x{1109}\x{1107}\x{1100}/g;
  s/\x{1134}/\x{1109}\x{1109}\x{1109}/g;
  s/\x{1101}/\x{1100}\x{1100}/g;
  s/\x{1113}/\x{1102}\x{1100}/g;
  s/\x{1114}/\x{1102}\x{1102}/g;
  s/\x{1115}/\x{1102}\x{1103}/g;
  s/\x{1116}/\x{1102}\x{1107}/g;
  s/\x{1117}/\x{1103}\x{1100}/g;
  s/\x{1104}/\x{1103}\x{1103}/g;
  s/\x{1118}/\x{1105}\x{1102}/g;
  s/\x{1119}/\x{1105}\x{1105}/g;
  s/\x{111B}/\x{1105}\x{110B}/g;
  s/\x{111A}/\x{1105}\x{1112}/g;
  s/\x{111C}/\x{1106}\x{1107}/g;
  s/\x{111D}/\x{1106}\x{110B}/g;
  s/\x{111E}/\x{1107}\x{1100}/g;
  s/\x{111F}/\x{1107}\x{1102}/g;
  s/\x{1120}/\x{1107}\x{1103}/g;
  s/\x{1108}/\x{1107}\x{1107}/g;
  s/\x{1121}/\x{1107}\x{1109}/g;
  s/\x{112B}/\x{1107}\x{110B}/g;
  s/\x{1127}/\x{1107}\x{110C}/g;
  s/\x{1128}/\x{1107}\x{110E}/g;
  s/\x{1129}/\x{1107}\x{1110}/g;
  s/\x{112A}/\x{1107}\x{1111}/g;
  s/\x{112D}/\x{1109}\x{1100}/g;
  s/\x{112E}/\x{1109}\x{1102}/g;
  s/\x{112F}/\x{1109}\x{1103}/g;
  s/\x{1130}/\x{1109}\x{1105}/g;
  s/\x{1131}/\x{1109}\x{1106}/g;
  s/\x{1132}/\x{1109}\x{1107}/g;
  s/\x{110A}/\x{1109}\x{1109}/g;
  s/\x{1135}/\x{1109}\x{110B}/g;
  s/\x{1136}/\x{1109}\x{110C}/g;
  s/\x{1137}/\x{1109}\x{110E}/g;
  s/\x{1138}/\x{1109}\x{110F}/g;
  s/\x{1139}/\x{1109}\x{1110}/g;
  s/\x{113A}/\x{1109}\x{1111}/g;
  s/\x{113B}/\x{1109}\x{1112}/g;
  s/\x{1141}/\x{110B}\x{1100}/g;
  s/\x{1142}/\x{110B}\x{1103}/g;
  s/\x{1143}/\x{110B}\x{1106}/g;
  s/\x{1144}/\x{110B}\x{1107}/g;
  s/\x{1145}/\x{110B}\x{1109}/g;
  s/\x{1147}/\x{110B}\x{110B}/g;
  s/\x{1148}/\x{110B}\x{110C}/g;
  s/\x{1149}/\x{110B}\x{110E}/g;
  s/\x{114A}/\x{110B}\x{1110}/g;
  s/\x{114B}/\x{110B}\x{1111}/g;
  s/\x{1146}/\x{110B}\x{1140}/g;
  s/\x{114D}/\x{110C}\x{110B}/g;
  s/\x{110D}/\x{110C}\x{110C}/g;
  s/\x{1152}/\x{110E}\x{110F}/g;
  s/\x{1153}/\x{110E}\x{1112}/g;
  s/\x{1156}/\x{1111}\x{1107}/g;
  s/\x{1157}/\x{1111}\x{110B}/g;
  s/\x{1158}/\x{1112}\x{1112}/g;
  s/\x{114F}/\x{114E}\x{114E}/g;
  s/\x{1151}/\x{1150}\x{1150}/g;
  s/\x{116B}/\x{1169}\x{1161}\x{1175}/g;
  s/\x{1180}/\x{1169}\x{1165}\x{1175}/g;
  s/\x{1181}/\x{1169}\x{1167}\x{1175}/g;
  s/\x{1185}/\x{116D}\x{1163}\x{1175}/g;
  s/\x{118A}/\x{116E}\x{1161}\x{1175}/g;
  s/\x{118B}/\x{116E}\x{1165}\x{1173}/g;
  s/\x{1170}/\x{116E}\x{1165}\x{1175}/g;
  s/\x{118C}/\x{116E}\x{1167}\x{1175}/g;
  s/\x{1190}/\x{1172}\x{1165}\x{1175}/g;
  s/\x{1192}/\x{1172}\x{1167}\x{1175}/g;
  s/\x{1197}/\x{1173}\x{1175}\x{116E}/g;
  s/\x{1176}/\x{1161}\x{1169}/g;
  s/\x{1177}/\x{1161}\x{116E}/g;
  s/\x{1162}/\x{1161}\x{1175}/g;
  s/\x{1178}/\x{1163}\x{1169}/g;
  s/\x{1179}/\x{1163}\x{116D}/g;
  s/\x{1164}/\x{1163}\x{1175}/g;
  s/\x{117A}/\x{1165}\x{1169}/g;
  s/\x{117B}/\x{1165}\x{116E}/g;
  s/\x{117C}/\x{1165}\x{1173}/g;
  s/\x{1166}/\x{1165}\x{1175}/g;
  s/\x{117D}/\x{1167}\x{1169}/g;
  s/\x{117E}/\x{1167}\x{116E}/g;
  s/\x{1168}/\x{1167}\x{1175}/g;
  s/\x{116A}/\x{1169}\x{1161}/g;
  s/\x{117F}/\x{1169}\x{1165}/g;
  s/\x{1182}/\x{1169}\x{1169}/g;
  s/\x{1183}/\x{1169}\x{116E}/g;
  s/\x{116C}/\x{1169}\x{1175}/g;
  s/\x{1184}/\x{116D}\x{1163}/g;
  s/\x{1186}/\x{116D}\x{1167}/g;
  s/\x{1187}/\x{116D}\x{1169}/g;
  s/\x{1188}/\x{116D}\x{1175}/g;
  s/\x{1189}/\x{116E}\x{1161}/g;
  s/\x{116F}/\x{116E}\x{1165}/g;
  s/\x{118D}/\x{116E}\x{116E}/g;
  s/\x{1171}/\x{116E}\x{1175}/g;
  s/\x{118E}/\x{1172}\x{1161}/g;
  s/\x{118F}/\x{1172}\x{1165}/g;
  s/\x{1191}/\x{1172}\x{1167}/g;
  s/\x{1193}/\x{1172}\x{116E}/g;
  s/\x{1194}/\x{1172}\x{1175}/g;
  s/\x{1195}/\x{1173}\x{116E}/g;
  s/\x{1196}/\x{1173}\x{1173}/g;
  s/\x{1174}/\x{1173}\x{1175}/g;
  s/\x{1198}/\x{1175}\x{1161}/g;
  s/\x{1199}/\x{1175}\x{1163}/g;
  s/\x{119A}/\x{1175}\x{1169}/g;
  s/\x{119B}/\x{1175}\x{116E}/g;
  s/\x{119C}/\x{1175}\x{1173}/g;
  s/\x{119D}/\x{1175}\x{119E}/g;
  s/\x{119F}/\x{119E}\x{1165}/g;
  s/\x{11A0}/\x{119E}\x{116E}/g;
  s/\x{11A1}/\x{119E}\x{1175}/g;
  s/\x{11A2}/\x{119E}\x{119E}/g;
  s/\x{11C4}/\x{11A8}\x{11BA}\x{11A8}/g;
  s/\x{11CC}/\x{11AF}\x{11A8}\x{11BA}/g;
  s/\x{11CF}/\x{11AF}\x{11AE}\x{11C2}/g;
  s/\x{11D1}/\x{11AF}\x{11B7}\x{11A8}/g;
  s/\x{11D2}/\x{11AF}\x{11B7}\x{11BA}/g;
  s/\x{11D3}/\x{11AF}\x{11B8}\x{11BA}/g;
  s/\x{11D5}/\x{11AF}\x{11B8}\x{11BC}/g;
  s/\x{11D4}/\x{11AF}\x{11B8}\x{11C2}/g;
  s/\x{11D6}/\x{11AF}\x{11BA}\x{11BA}/g;
  s/\x{11DE}/\x{11B7}\x{11BA}\x{11BA}/g;
  s/\x{11ED}/\x{11BC}\x{11A8}\x{11A8}/g;
  s/\x{11A9}/\x{11A8}\x{11A8}/g;
  s/\x{11C3}/\x{11A8}\x{11AF}/g;
  s/\x{11AA}/\x{11A8}\x{11BA}/g;
  s/\x{11C5}/\x{11AB}\x{11A8}/g;
  s/\x{11C6}/\x{11AB}\x{11AE}/g;
  s/\x{11C7}/\x{11AB}\x{11BA}/g;
  s/\x{11AC}/\x{11AB}\x{11BD}/g;
  s/\x{11C9}/\x{11AB}\x{11C0}/g;
  s/\x{11AD}/\x{11AB}\x{11C2}/g;
  s/\x{11C8}/\x{11AB}\x{11EB}/g;
  s/\x{11CA}/\x{11AE}\x{11A8}/g;
  s/\x{11CB}/\x{11AE}\x{11AF}/g;
  s/\x{11B0}/\x{11AF}\x{11A8}/g;
  s/\x{11CD}/\x{11AF}\x{11AB}/g;
  s/\x{11CE}/\x{11AF}\x{11AE}/g;
  s/\x{11D0}/\x{11AF}\x{11AF}/g;
  s/\x{11B1}/\x{11AF}\x{11B7}/g;
  s/\x{11B2}/\x{11AF}\x{11B8}/g;
  s/\x{11B3}/\x{11AF}\x{11BA}/g;
  s/\x{11D8}/\x{11AF}\x{11BF}/g;
  s/\x{11B4}/\x{11AF}\x{11C0}/g;
  s/\x{11B5}/\x{11AF}\x{11C1}/g;
  s/\x{11B6}/\x{11AF}\x{11C2}/g;
  s/\x{11D7}/\x{11AF}\x{11EB}/g;
  s/\x{11D9}/\x{11AF}\x{11F9}/g;
  s/\x{11DA}/\x{11B7}\x{11A8}/g;
  s/\x{11DB}/\x{11B7}\x{11AF}/g;
  s/\x{11DC}/\x{11B7}\x{11B8}/g;
  s/\x{11DD}/\x{11B7}\x{11BA}/g;
  s/\x{11E2}/\x{11B7}\x{11BC}/g;
  s/\x{11E0}/\x{11B7}\x{11BE}/g;
  s/\x{11E1}/\x{11B7}\x{11C2}/g;
  s/\x{11DF}/\x{11B7}\x{11EB}/g;
  s/\x{11E3}/\x{11B8}\x{11AF}/g;
  s/\x{11B9}/\x{11B8}\x{11BA}/g;
  s/\x{11E6}/\x{11B8}\x{11BC}/g;
  s/\x{11E4}/\x{11B8}\x{11C1}/g;
  s/\x{11E5}/\x{11B8}\x{11C2}/g;
  s/\x{11E7}/\x{11BA}\x{11A8}/g;
  s/\x{11E8}/\x{11BA}\x{11AE}/g;
  s/\x{11E9}/\x{11BA}\x{11AF}/g;
  s/\x{11EA}/\x{11BA}\x{11B8}/g;
  s/\x{11BB}/\x{11BA}\x{11BA}/g;
  s/\x{11EC}/\x{11BC}\x{11A8}/g;
  s/\x{11EE}/\x{11BC}\x{11BC}/g;
  s/\x{11EF}/\x{11BC}\x{11BF}/g;
  s/\x{11F3}/\x{11C1}\x{11B8}/g;
  s/\x{11F4}/\x{11C1}\x{11BC}/g;
  s/\x{11F5}/\x{11C2}\x{11AB}/g;
  s/\x{11F6}/\x{11C2}\x{11AF}/g;
  s/\x{11F7}/\x{11C2}\x{11B7}/g;
  s/\x{11F8}/\x{11C2}\x{11B8}/g;
  s/\x{11F1}/\x{11F0}\x{11BA}/g;
  s/\x{11F2}/\x{11F0}\x{11EB}/g;
}

sub jamo_to_puajamo {
  s/\x{1105}\x{1100}\x{1100}/\x{F79A}/g;
  s/\x{1105}\x{1103}\x{1103}/\x{F79D}/g;
  s/\x{1105}\x{1107}\x{1107}/\x{F7A1}/g;
  s/\x{1105}\x{1107}\x{110B}/\x{F7A2}/g;
  s/\x{1107}\x{1109}\x{1100}/\x{F7B4}/g;
  s/\x{1107}\x{1109}\x{1103}/\x{F7B5}/g;
  s/\x{1107}\x{1109}\x{1107}/\x{F7B6}/g;
  s/\x{1107}\x{1109}\x{1109}/\x{F7B7}/g;
  s/\x{1107}\x{1109}\x{110C}/\x{F7B8}/g;
  s/\x{1107}\x{1109}\x{1110}/\x{F7B9}/g;
  s/\x{1107}\x{1107}\x{110B}/\x{F7C1}/g;
  s/\x{1109}\x{1107}\x{1100}/\x{F7C9}/g;
  s/\x{1109}\x{1109}\x{1107}/\x{F7CB}/g;
  s/\x{1109}\x{1109}\x{1109}/\x{F7CC}/g;
  s/\x{110C}\x{110C}\x{1112}/\x{F7EB}/g;
  s/\x{1169}\x{1161}\x{1175}/\x{F81D}/g;
  s/\x{1169}\x{1163}\x{1175}/\x{F81F}/g;
  s/\x{1169}\x{1165}\x{1175}/\x{F821}/g;
  s/\x{1169}\x{1167}\x{1175}/\x{F823}/g;
  s/\x{1169}\x{1169}\x{116E}/\x{F825}/g;
  s/\x{116D}\x{1161}\x{1175}/\x{F82A}/g;
  s/\x{116D}\x{1163}\x{1175}/\x{F82C}/g;
  s/\x{116E}\x{1161}\x{1175}/\x{F833}/g;
  s/\x{116E}\x{1165}\x{1173}/\x{F835}/g;
  s/\x{116E}\x{1165}\x{1175}/\x{F836}/g;
  s/\x{116E}\x{1167}\x{1175}/\x{F838}/g;
  s/\x{116E}\x{1175}\x{1175}/\x{F83B}/g;
  s/\x{1172}\x{1161}\x{1175}/\x{F83E}/g;
  s/\x{1172}\x{1165}\x{1175}/\x{F840}/g;
  s/\x{1172}\x{1167}\x{1175}/\x{F842}/g;
  s/\x{1173}\x{1165}\x{1175}/\x{F849}/g;
  s/\x{1173}\x{1175}\x{116E}/\x{F84E}/g;
  s/\x{1175}\x{1163}\x{1169}/\x{F852}/g;
  s/\x{1175}\x{1163}\x{1175}/\x{F853}/g;
  s/\x{1175}\x{1167}\x{1175}/\x{F855}/g;
  s/\x{1175}\x{1169}\x{116E}/\x{F857}/g;
  s/\x{119E}\x{1165}\x{1175}/\x{F861}/g;
  s/\x{11A8}\x{11BA}\x{11A8}/\x{F871}/g;
  s/\x{11AE}\x{11AE}\x{11B8}/\x{F883}/g;
  s/\x{11AE}\x{11BA}\x{11A8}/\x{F887}/g;
  s/\x{11AF}\x{11A8}\x{11A8}/\x{F88D}/g;
  s/\x{11AF}\x{11A8}\x{11BA}/\x{F88E}/g;
  s/\x{11AF}\x{11A8}\x{11C2}/\x{F88F}/g;
  s/\x{11AF}\x{11AE}\x{11C2}/\x{F892}/g;
  s/\x{11AF}\x{11AF}\x{11BF}/\x{F894}/g;
  s/\x{11AF}\x{11B7}\x{11A8}/\x{F896}/g;
  s/\x{11AF}\x{11B7}\x{11BA}/\x{F897}/g;
  s/\x{11AF}\x{11B7}\x{11C2}/\x{F898}/g;
  s/\x{11AF}\x{11B8}\x{11AE}/\x{F89A}/g;
  s/\x{11AF}\x{11B8}\x{11BA}/\x{F89B}/g;
  s/\x{11AF}\x{11B8}\x{11C1}/\x{F89C}/g;
  s/\x{11AF}\x{11B8}\x{11C2}/\x{F89D}/g;
  s/\x{11AF}\x{11B8}\x{11BC}/\x{F89E}/g;
  s/\x{11AF}\x{11BA}\x{11BA}/\x{F8A0}/g;
  s/\x{11AF}\x{11F9}\x{11C2}/\x{F8A8}/g;
  s/\x{11B7}\x{11AB}\x{11AB}/\x{F8AD}/g;
  s/\x{11B7}\x{11B8}\x{11BA}/\x{F8B1}/g;
  s/\x{11B7}\x{11BA}\x{11BA}/\x{F8B3}/g;
  s/\x{11B8}\x{11AF}\x{11C1}/\x{F8BC}/g;
  s/\x{11B8}\x{11BA}\x{11AE}/\x{F8C0}/g;
  s/\x{11BA}\x{11B8}\x{11BC}/\x{F8CC}/g;
  s/\x{11BA}\x{11BA}\x{11A8}/\x{F8CE}/g;
  s/\x{11BA}\x{11BA}\x{11AE}/\x{F8CF}/g;
  s/\x{11EB}\x{11B8}\x{11BC}/\x{F8D7}/g;
  s/\x{11BC}\x{11A8}\x{11A8}/\x{F8DA}/g;
  s/\x{11BD}\x{11B8}\x{11B8}/\x{F8E8}/g;
  s/\x{1100}\x{1100}/\x{F786}/g;
  s/\x{1100}\x{1103}/\x{F787}/g;
  s/\x{1102}\x{1100}/\x{F789}/g;
  s/\x{1102}\x{1102}/\x{F78A}/g;
  s/\x{1102}\x{1103}/\x{F78B}/g;
  s/\x{1102}\x{1107}/\x{F78C}/g;
  s/\x{1102}\x{1109}/\x{F78D}/g;
  s/\x{1102}\x{110C}/\x{F78E}/g;
  s/\x{1102}\x{1112}/\x{F78F}/g;
  s/\x{1103}\x{1100}/\x{F791}/g;
  s/\x{1103}\x{1103}/\x{F792}/g;
  s/\x{1103}\x{1105}/\x{F793}/g;
  s/\x{1103}\x{1106}/\x{F794}/g;
  s/\x{1103}\x{1107}/\x{F795}/g;
  s/\x{1103}\x{1109}/\x{F796}/g;
  s/\x{1103}\x{110C}/\x{F797}/g;
  s/\x{1105}\x{1100}/\x{F799}/g;
  s/\x{1105}\x{1102}/\x{F79B}/g;
  s/\x{1105}\x{1103}/\x{F79C}/g;
  s/\x{1105}\x{1105}/\x{F79E}/g;
  s/\x{1105}\x{1106}/\x{F79F}/g;
  s/\x{1105}\x{1107}/\x{F7A0}/g;
  s/\x{1105}\x{1109}/\x{F7A3}/g;
  s/\x{1105}\x{110C}/\x{F7A4}/g;
  s/\x{1105}\x{110F}/\x{F7A5}/g;
  s/\x{1105}\x{1112}/\x{F7A6}/g;
  s/\x{1105}\x{110B}/\x{F7A7}/g;
  s/\x{1106}\x{1100}/\x{F7A9}/g;
  s/\x{1106}\x{1103}/\x{F7AA}/g;
  s/\x{1106}\x{1107}/\x{F7AB}/g;
  s/\x{1106}\x{1109}/\x{F7AC}/g;
  s/\x{1106}\x{110B}/\x{F7AD}/g;
  s/\x{1107}\x{1100}/\x{F7AF}/g;
  s/\x{1107}\x{1102}/\x{F7B0}/g;
  s/\x{1107}\x{1103}/\x{F7B1}/g;
  s/\x{1107}\x{1107}/\x{F7B2}/g;
  s/\x{1107}\x{1109}/\x{F7B3}/g;
  s/\x{1107}\x{110C}/\x{F7BA}/g;
  s/\x{1107}\x{110E}/\x{F7BB}/g;
  s/\x{1107}\x{110F}/\x{F7BC}/g;
  s/\x{1107}\x{1110}/\x{F7BD}/g;
  s/\x{1107}\x{1111}/\x{F7BE}/g;
  s/\x{1107}\x{1112}/\x{F7BF}/g;
  s/\x{1107}\x{110B}/\x{F7C0}/g;
  s/\x{1109}\x{1100}/\x{F7C3}/g;
  s/\x{1109}\x{1102}/\x{F7C4}/g;
  s/\x{1109}\x{1103}/\x{F7C5}/g;
  s/\x{1109}\x{1105}/\x{F7C6}/g;
  s/\x{1109}\x{1106}/\x{F7C7}/g;
  s/\x{1109}\x{1107}/\x{F7C8}/g;
  s/\x{1109}\x{1109}/\x{F7CA}/g;
  s/\x{1109}\x{110B}/\x{F7CD}/g;
  s/\x{1109}\x{110C}/\x{F7CE}/g;
  s/\x{1109}\x{110E}/\x{F7CF}/g;
  s/\x{1109}\x{110F}/\x{F7D0}/g;
  s/\x{1109}\x{1110}/\x{F7D1}/g;
  s/\x{1109}\x{1111}/\x{F7D2}/g;
  s/\x{1109}\x{1112}/\x{F7D3}/g;
  s/\x{110B}\x{1100}/\x{F7DA}/g;
  s/\x{110B}\x{1103}/\x{F7DB}/g;
  s/\x{110B}\x{1105}/\x{F7DC}/g;
  s/\x{110B}\x{1106}/\x{F7DD}/g;
  s/\x{110B}\x{1107}/\x{F7DE}/g;
  s/\x{110B}\x{1109}/\x{F7DF}/g;
  s/\x{110B}\x{1140}/\x{F7E0}/g;
  s/\x{110B}\x{110B}/\x{F7E1}/g;
  s/\x{110B}\x{110C}/\x{F7E2}/g;
  s/\x{110B}\x{110E}/\x{F7E3}/g;
  s/\x{110B}\x{1110}/\x{F7E4}/g;
  s/\x{110B}\x{1111}/\x{F7E5}/g;
  s/\x{110B}\x{1112}/\x{F7E6}/g;
  s/\x{110C}\x{110B}/\x{F7E9}/g;
  s/\x{110C}\x{110C}/\x{F7EA}/g;
  s/\x{114E}\x{114E}/\x{F7ED}/g;
  s/\x{1150}\x{1150}/\x{F7EF}/g;
  s/\x{110E}\x{110F}/\x{F7F1}/g;
  s/\x{110E}\x{1112}/\x{F7F2}/g;
  s/\x{1110}\x{1110}/\x{F7F7}/g;
  s/\x{1111}\x{1107}/\x{F7F9}/g;
  s/\x{1111}\x{1112}/\x{F7FA}/g;
  s/\x{1111}\x{110B}/\x{F7FB}/g;
  s/\x{1112}\x{1109}/\x{F7FD}/g;
  s/\x{1112}\x{1112}/\x{F7FE}/g;
  s/\x{1159}\x{1159}/\x{F800}/g;
  s/\x{1161}\x{1169}/\x{F808}/g;
  s/\x{1161}\x{116E}/\x{F809}/g;
  s/\x{1161}\x{1173}/\x{F80A}/g;
  s/\x{1161}\x{1175}/\x{F80B}/g;
  s/\x{1163}\x{1169}/\x{F80D}/g;
  s/\x{1163}\x{116D}/\x{F80E}/g;
  s/\x{1163}\x{116E}/\x{F80F}/g;
  s/\x{1163}\x{1175}/\x{F810}/g;
  s/\x{1165}\x{1169}/\x{F812}/g;
  s/\x{1165}\x{116E}/\x{F813}/g;
  s/\x{1165}\x{1173}/\x{F814}/g;
  s/\x{1165}\x{1175}/\x{F815}/g;
  s/\x{1167}\x{1163}/\x{F817}/g;
  s/\x{1167}\x{1169}/\x{F818}/g;
  s/\x{1167}\x{116E}/\x{F819}/g;
  s/\x{1167}\x{1175}/\x{F81A}/g;
  s/\x{1169}\x{1161}/\x{F81C}/g;
  s/\x{1169}\x{1163}/\x{F81E}/g;
  s/\x{1169}\x{1165}/\x{F820}/g;
  s/\x{1169}\x{1167}/\x{F822}/g;
  s/\x{1169}\x{1169}/\x{F824}/g;
  s/\x{1169}\x{116E}/\x{F826}/g;
  s/\x{1169}\x{1175}/\x{F827}/g;
  s/\x{116D}\x{1161}/\x{F829}/g;
  s/\x{116D}\x{1163}/\x{F82B}/g;
  s/\x{116D}\x{1165}/\x{F82D}/g;
  s/\x{116D}\x{1167}/\x{F82E}/g;
  s/\x{116D}\x{1169}/\x{F82F}/g;
  s/\x{116D}\x{1175}/\x{F830}/g;
  s/\x{116E}\x{1161}/\x{F832}/g;
  s/\x{116E}\x{1165}/\x{F834}/g;
  s/\x{116E}\x{1167}/\x{F837}/g;
  s/\x{116E}\x{116E}/\x{F839}/g;
  s/\x{116E}\x{1175}/\x{F83A}/g;
  s/\x{1172}\x{1161}/\x{F83D}/g;
  s/\x{1172}\x{1165}/\x{F83F}/g;
  s/\x{1172}\x{1167}/\x{F841}/g;
  s/\x{1172}\x{1169}/\x{F843}/g;
  s/\x{1172}\x{116E}/\x{F844}/g;
  s/\x{1172}\x{1175}/\x{F845}/g;
  s/\x{1173}\x{1161}/\x{F847}/g;
  s/\x{1173}\x{1165}/\x{F848}/g;
  s/\x{1173}\x{1169}/\x{F84A}/g;
  s/\x{1173}\x{116E}/\x{F84B}/g;
  s/\x{1173}\x{1173}/\x{F84C}/g;
  s/\x{1173}\x{1175}/\x{F84D}/g;
  s/\x{1175}\x{1161}/\x{F850}/g;
  s/\x{1175}\x{1163}/\x{F851}/g;
  s/\x{1175}\x{1167}/\x{F854}/g;
  s/\x{1175}\x{1169}/\x{F856}/g;
  s/\x{1175}\x{116D}/\x{F858}/g;
  s/\x{1175}\x{116E}/\x{F859}/g;
  s/\x{1175}\x{1172}/\x{F85A}/g;
  s/\x{1175}\x{1173}/\x{F85B}/g;
  s/\x{1175}\x{1175}/\x{F85C}/g;
  s/\x{1175}\x{119E}/\x{F85D}/g;
  s/\x{119E}\x{1161}/\x{F85F}/g;
  s/\x{119E}\x{1165}/\x{F860}/g;
  s/\x{119E}\x{116E}/\x{F862}/g;
  s/\x{119E}\x{1175}/\x{F863}/g;
  s/\x{119E}\x{119E}/\x{F864}/g;
  s/\x{11A8}\x{11A8}/\x{F86C}/g;
  s/\x{11A8}\x{11AB}/\x{F86D}/g;
  s/\x{11A8}\x{11AF}/\x{F86E}/g;
  s/\x{11A8}\x{11B8}/\x{F86F}/g;
  s/\x{11A8}\x{11BA}/\x{F870}/g;
  s/\x{11A8}\x{11BE}/\x{F872}/g;
  s/\x{11A8}\x{11BF}/\x{F873}/g;
  s/\x{11A8}\x{11C2}/\x{F874}/g;
  s/\x{11AB}\x{11A8}/\x{F876}/g;
  s/\x{11AB}\x{11AB}/\x{F877}/g;
  s/\x{11AB}\x{11AE}/\x{F878}/g;
  s/\x{11AB}\x{11AF}/\x{F879}/g;
  s/\x{11AB}\x{11BA}/\x{F87A}/g;
  s/\x{11AB}\x{11EB}/\x{F87B}/g;
  s/\x{11AB}\x{11BD}/\x{F87C}/g;
  s/\x{11AB}\x{11BE}/\x{F87D}/g;
  s/\x{11AB}\x{11C0}/\x{F87E}/g;
  s/\x{11AB}\x{11C2}/\x{F87F}/g;
  s/\x{11AE}\x{11A8}/\x{F881}/g;
  s/\x{11AE}\x{11AE}/\x{F882}/g;
  s/\x{11AE}\x{11AF}/\x{F884}/g;
  s/\x{11AE}\x{11B8}/\x{F885}/g;
  s/\x{11AE}\x{11BA}/\x{F886}/g;
  s/\x{11AE}\x{11BD}/\x{F888}/g;
  s/\x{11AE}\x{11BE}/\x{F889}/g;
  s/\x{11AE}\x{11C0}/\x{F88A}/g;
  s/\x{11AF}\x{11A8}/\x{F88C}/g;
  s/\x{11AF}\x{11AB}/\x{F890}/g;
  s/\x{11AF}\x{11AE}/\x{F891}/g;
  s/\x{11AF}\x{11AF}/\x{F893}/g;
  s/\x{11AF}\x{11B7}/\x{F895}/g;
  s/\x{11AF}\x{11B8}/\x{F899}/g;
  s/\x{11AF}\x{11BA}/\x{F89F}/g;
  s/\x{11AF}\x{11EB}/\x{F8A1}/g;
  s/\x{11AF}\x{11F0}/\x{F8A2}/g;
  s/\x{11AF}\x{11BF}/\x{F8A3}/g;
  s/\x{11AF}\x{11C0}/\x{F8A4}/g;
  s/\x{11AF}\x{11C1}/\x{F8A5}/g;
  s/\x{11AF}\x{11C2}/\x{F8A6}/g;
  s/\x{11AF}\x{11F9}/\x{F8A7}/g;
  s/\x{11AF}\x{11BC}/\x{F8A9}/g;
  s/\x{11B7}\x{11A8}/\x{F8AB}/g;
  s/\x{11B7}\x{11AB}/\x{F8AC}/g;
  s/\x{11B7}\x{11AF}/\x{F8AE}/g;
  s/\x{11B7}\x{11B7}/\x{F8AF}/g;
  s/\x{11B7}\x{11B8}/\x{F8B0}/g;
  s/\x{11B7}\x{11BA}/\x{F8B2}/g;
  s/\x{11B7}\x{11EB}/\x{F8B4}/g;
  s/\x{11B7}\x{11BD}/\x{F8B5}/g;
  s/\x{11B7}\x{11BE}/\x{F8B6}/g;
  s/\x{11B7}\x{11C2}/\x{F8B7}/g;
  s/\x{11B7}\x{11BC}/\x{F8B8}/g;
  s/\x{11B8}\x{11AE}/\x{F8BA}/g;
  s/\x{11B8}\x{11AF}/\x{F8BB}/g;
  s/\x{11B8}\x{11B7}/\x{F8BD}/g;
  s/\x{11B8}\x{11B8}/\x{F8BE}/g;
  s/\x{11B8}\x{11BA}/\x{F8BF}/g;
  s/\x{11B8}\x{11BD}/\x{F8C1}/g;
  s/\x{11B8}\x{11BE}/\x{F8C2}/g;
  s/\x{11B8}\x{11C1}/\x{F8C3}/g;
  s/\x{11B8}\x{11C2}/\x{F8C4}/g;
  s/\x{11B8}\x{11BC}/\x{F8C5}/g;
  s/\x{11BA}\x{11A8}/\x{F8C7}/g;
  s/\x{11BA}\x{11AE}/\x{F8C8}/g;
  s/\x{11BA}\x{11AF}/\x{F8C9}/g;
  s/\x{11BA}\x{11B7}/\x{F8CA}/g;
  s/\x{11BA}\x{11B8}/\x{F8CB}/g;
  s/\x{11BA}\x{11BA}/\x{F8CD}/g;
  s/\x{11BA}\x{11EB}/\x{F8D0}/g;
  s/\x{11BA}\x{11BD}/\x{F8D1}/g;
  s/\x{11BA}\x{11BE}/\x{F8D2}/g;
  s/\x{11BA}\x{11C0}/\x{F8D3}/g;
  s/\x{11BA}\x{11C2}/\x{F8D4}/g;
  s/\x{11EB}\x{11B8}/\x{F8D6}/g;
  s/\x{11BC}\x{11A8}/\x{F8D9}/g;
  s/\x{11BC}\x{11B7}/\x{F8DB}/g;
  s/\x{11BC}\x{11BA}/\x{F8DC}/g;
  s/\x{11BC}\x{11BC}/\x{F8DD}/g;
  s/\x{11BC}\x{11BF}/\x{F8DE}/g;
  s/\x{11BC}\x{11C2}/\x{F8DF}/g;
  s/\x{11F0}\x{11A8}/\x{F8E1}/g;
  s/\x{11F0}\x{11BA}/\x{F8E2}/g;
  s/\x{11F0}\x{11EB}/\x{F8E3}/g;
  s/\x{11F0}\x{11BF}/\x{F8E4}/g;
  s/\x{11F0}\x{11C2}/\x{F8E5}/g;
  s/\x{11BD}\x{11B8}/\x{F8E7}/g;
  s/\x{11BD}\x{11BD}/\x{F8E9}/g;
  s/\x{11C1}\x{11B8}/\x{F8EE}/g;
  s/\x{11C1}\x{11BA}/\x{F8EF}/g;
  s/\x{11C1}\x{11C0}/\x{F8F0}/g;
  s/\x{11C1}\x{11BC}/\x{F8F1}/g;
  s/\x{11C2}\x{11AB}/\x{F8F3}/g;
  s/\x{11C2}\x{11AF}/\x{F8F4}/g;
  s/\x{11C2}\x{11B7}/\x{F8F5}/g;
  s/\x{11C2}\x{11B8}/\x{F8F6}/g;
  s/\x{115F}/\x{F801}/g;	# s/\x{115F}/\x{F784}/g; # 초성채움.
  s/\x{1100}/\x{F785}/g;
  s/\x{1102}/\x{F788}/g;
  s/\x{1103}/\x{F790}/g;
  s/\x{1105}/\x{F798}/g;
  s/\x{1106}/\x{F7A8}/g;
  s/\x{1107}/\x{F7AE}/g;
  s/\x{1109}/\x{F7C2}/g;
  s/\x{113C}/\x{F7D4}/g;
  s/\x{113D}/\x{F7D5}/g;
  s/\x{113E}/\x{F7D6}/g;
  s/\x{113F}/\x{F7D7}/g;
  s/\x{1140}/\x{F7D8}/g;
  s/\x{110B}/\x{F7D9}/g;
  s/\x{114C}/\x{F7E7}/g;
  s/\x{110C}/\x{F7E8}/g;
  s/\x{114E}/\x{F7EC}/g;
  s/\x{1150}/\x{F7EE}/g;
  s/\x{110E}/\x{F7F0}/g;
  s/\x{1154}/\x{F7F3}/g;
  s/\x{1155}/\x{F7F4}/g;
  s/\x{110F}/\x{F7F5}/g;
  s/\x{1110}/\x{F7F6}/g;
  s/\x{1111}/\x{F7F8}/g;
  s/\x{1112}/\x{F7FC}/g;
  s/\x{1159}/\x{F7FF}/g;
  s/\x{1160}/\x{F806}/g;	# 중성채움.
  s/\x{1161}/\x{F807}/g;
  s/\x{1163}/\x{F80C}/g;
  s/\x{1165}/\x{F811}/g;
  s/\x{1167}/\x{F816}/g;
  s/\x{1169}/\x{F81B}/g;
  s/\x{116D}/\x{F828}/g;
  s/\x{116E}/\x{F831}/g;
  s/\x{1172}/\x{F83C}/g;
  s/\x{1173}/\x{F846}/g;
  s/\x{1175}/\x{F84F}/g;
  s/\x{119E}/\x{F85E}/g;
  s/\x{11A8}/\x{F86B}/g;
  s/\x{11AB}/\x{F875}/g;
  s/\x{11AE}/\x{F880}/g;
  s/\x{11AF}/\x{F88B}/g;
  s/\x{11B7}/\x{F8AA}/g;
  s/\x{11B8}/\x{F8B9}/g;
  s/\x{11BA}/\x{F8C6}/g;
  s/\x{11EB}/\x{F8D5}/g;
  s/\x{11BC}/\x{F8D8}/g;
  s/\x{11BD}/\x{F8E6}/g;
  s/\x{11F0}/\x{F8E0}/g;
  s/\x{11BE}/\x{F8EA}/g;
  s/\x{11BF}/\x{F8EB}/g;
  s/\x{11C0}/\x{F8EC}/g;
  s/\x{11C1}/\x{F8ED}/g;
  s/\x{11C2}/\x{F8F2}/g;
  s/\x{11F9}/\x{F8F7}/g;
  s/\x{11A7}/\x{F86A}/g;	### jongseong filler
}

### EOF
